Eric said:
So:
def foo; 456; end unless defined? foo
puts foo
will print 456, because at parse time foo is undefined, even though it
gets made into a method name at runtime.
Almost - perhaps I muddied things a bit. At parse time, in the above
code, foo is not 'undefined'; it is known that it must be a method name,
because it's not a local variable. But it's not known whether there will
be a method called foo at the time this code is executed.
So, the result of defined?(foo) is decided at runtime. But if foo is a
local variable at that point in the source code (which is decided at
parse time), then you always know that the result of defined?(foo) will
be "local-variable", since the parse tree contains "NODE_LVAR foo"; the
parser had already chosen foo to be a local variable, and this is a fact
which cannot be altered subsequently.
I don't think the MRI interpreter actually optimises away defined?(LVAR)
to a constant at parse time as I might have implied, but in theory it
could.
For methods, the result is not known until runtime. Example:
nil
method
=> 2