In ruby, why not defined? work as you would expect when used with

I am running ruby ​​1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux].

#!/usr/bin/env ruby def ouch() raise ArgumentError, "woof" fred = 3 return( nil ) ensure if ( defined?( fred ) ) then printf( "fred is defined (%s)\n", fred.inspect() ) else printf( "fred is not defined\n" ) end end # ouch() ouch() 

At startup, the output from the above ruby ​​script is quite unexpected.

  $ ./ouch.rb fred is defined (nil) ./ouch.rb:4:in `ouch': woof (ArgumentError) from ./ouch.rb:22:in `<main>' 

Thus, an increase / exception occurs, fred does not get the value 3, but it is determined and set to zero, thereby defeating the test for determined by? (). This is very confusing. This is mistake? Obviously, a test for certain needs needs to be tested for not zero.

If this is not a mistake, can someone explain why not?

+6
source share
2 answers

Local variables in Ruby are defined between the line in which they are first used, and at the end of the current lexical region. They are also implicitly initialized to nil .

Consider also this example:

 if false var = 123 end p var # => nil 

This behavior is intended. Ruby is designed so that it can distinguish between method calls and local access to a variable at the analysis stage, rather than one. So, after the point at which the variable was defined, all further references to this name will refer to the variable, regardless of whether it was explicitly set to any value or not.

(If someone points me to the method of calling CALL_VCALL in Ruby, I will answer, as far as I know, this is used only in eval : if you are eval , you cannot know from the very beginning if any variable was defined in the previous one the irb line, so such calls should be caught and sent accordingly.)

+7
source
  • No mistake
  • Local variables are created by assignment, but it turns out that the assignment needs to be analyzed, not actually performed ...

Here is a simpler example:

  if false alocal = 123 end p defined? alocal => "local-variable" 
+4
source

Source: https://habr.com/ru/post/894492/


All Articles