A name considered a local variable on RHS of an assignment that defines it
The following script defines a method "f" and then a variable "f" by an assignment . There is a reference to "f" on RHS of the assignment. The parser treats this reference as a reference to the local variable "f", not to the method "f", since it has already seen an assignemnt to "f". However, one might expect that within the RHS of an assignment the local variable defined by the assignment should not be visible yet (and indeed its value is nil). The following code should therefore print 123 and and not nil.
f = f.inspect # 
Updated by shyouhei (Shyouhei Urabe) about 12 years ago
- Assignee set to matz (Yukihiro Matsumoto)
I don't think it being a bug, but a language design. You can always resolve a method
by prefixing "self." to the method name, but you can never add a qualifier to a local
variable, so in cases of naming conflict between local variables vs. methods, it is
safer for ruby to take local variables, generally speaking. Multiple assignment can
go quite complex and LHS variables are not always nil when appearing on RHS.
irb(main):001:0> f, g, h = (f = 1), (f += 1), f.inspect
=> [1, 2, "2"]
Updated by headius (Charles Nutter) about 12 years ago
I agree with Shyouhei. There are many such cases where a variable may not yet have been assigned, but for consistency all future references should treat it as a variable.
Would you expect f to refer to the method or the variable after the if statement here:
def f; 123; end
if false; f = nil; end
Having a clear lifecycle for local variables that does not depend on what actually runs or doesn't run (or when it runs) is very important for both readability and performance. From the moment you see a direct assignment to f, it's a local variable from then on.
Updated by tmat (Tomas Matousek) about 12 years ago
You're basically saying that it's a matter of syntactic structure, not control flow structure and I agree. There is still a choice to be made while parsing the assignment expression: the parser might "visit" RHS first and then define variables in LHS or the other way around. Both options are valid, prioritizing RHS might eliminate some confusion.
Updated by mame (Yusuke Endoh) about 11 years ago
- Status changed from Open to Rejected
2009/3/19 Tomas Matousek firstname.lastname@example.org:
the parser might "visit" RHS first and then define variables in LHS or the other way around. Both options are valid, prioritizing RHS might eliminate some confusion.
Your proposal will break recursive proc. Consider:
fact = proc do |n|
if n <= 0
n * fact[n - 1]
#=> undefined local variable or method `fact' for main:Object (NameError)
This is a significant incompatibility issue.
So I reject this ticket.
Yusuke ENDOH email@example.com