Project

General

Profile

Bug #13543

Updated by eiko (eiko kokuma) almost 7 years ago

The following code snippet generates a strange error: 

 ~~~ ruby 
 def foo 
   @foo ||= "foo" 
 end 

 foo = foo.size 

 #=> undefined method 'size' for nil:NilClass (NoMethodError) 
 ~~~ 

 I expect the code to create a local variable `foo` which is assigned the value `3`. I expect this because in assignment, the right size of `=` is always resolved before being bound to the left side of `=`. In my mind, `foo` should refer to the `foo()` method right up to the point that a value is assigned to the local variable which shadows it. It is confusing and unexpected to have a period of limbo in which `foo()` is overshadowed by an unassigned local variable mid-declaration. 

 In other languages, declaration and initial assignments are atomic, so this code would throw errors: 

 In python: 

 ~~~ python 
 foo = foo 
 # NameError: name 'foo' is not defined 
 ~~~ 

 In rust: 

 
 ~~~ c 
 let foo = foo 
 // error: cannot find value 'foo' in this scope. 
 ~~~ 

 But in ruby, a variable can be instantly declared and assigned to itself: 

 
 ~~~ ruby 
 foo = foo 
 #=> nil 
 ~~~ 

 This goes against the common motifs of programming in ruby and other languages and can lead to the confusing error mentioned above. Is there a reason local variables should be declared prior to resolving the assignment expression in ruby? I could find no documented reason for this design choice, leading me to believe it is a bug.

Back