I don't understand ruby ​​local coverage

In this example

def foo(x) if(x > 5) bar = 100 end puts bar end 

Then foo (6) Outputs: 100 and foo (3) does not output anything.

However, if I changed the definition to

 def foo(x) if(x > 5) bar = 100 end puts bob end 

I get the error "undefined local variable or method".

So my question is why am I not getting this error when I call foo (3) and the bar is never set?

+47
ruby
Nov 11 2018-10-11
source share
5 answers

Here are a few things going on. Firstly, the variables declared inside the if block have the same local scope as the variables declared at the top level of the method, so bar is accessible outside the if . Secondly, you get this error because bob refers directly to the face. The Ruby interpreter has never seen it and has never seen it initialized before. However, he saw bar , initialized earlier, inside the if statement. Therefore, when he gets to the bar, he knows that he exists. Combine the two and answer.

+53
Nov 11 2018-10-11
source share

The second example is the red herring: the reason you get the exception is not because bob uninitialized because it is ambiguous. It is not possible to determine if this is a variable or a method.

Your first example works because uninitialized local variables (as well as global and instance variables) are evaluated to nil . Therefore, puts bar excellent: in one case, bar initialized to 100 , and this is evaluated as 100 , in the other case, it is not initialized and, therefore, evaluated as nil . puts calls to_s in its argument, which is defined for nil (it just returns an empty string), so everything is fine and dandy.

See also In Ruby, why after running irb, foo.nil? says undefined error and @ foo.nil? gives "true", and @@ wah.nil? gives an error again?

+14
Nov 11 2018-10-11
source share

So don’t take it as a gospel (since it is more based on observation and then on understanding), but it looks like the ruby ​​interpreter will mark any word (without the sigil in front of it) to the left of the equal sign as local. Your example is weird, it's even more bizarre

 def foo bar = bar puts bar // nil, which gets coerced into "" end 

I don’t understand why and how it works, but there you have it.

+3
Nov 11 '10 at 13:41
source share

foo(3) does not output anything. It prints a new line.

Using inspect will give you more hint:

 def foo(x) if(x > 5) bar = 100 end puts bar.inspect end foo(3) 

displays

 nil 

bar is a full-fledged variable that simply has a nil value.

+2
Mar 27 '12 at 1:15
source share

I'm not sure what you are asking. Running foo(3) with the second definition will always give an error, since bob never defined. The argument of the method does not change this.

0
Nov 11 2018-10-11
source share



All Articles