Assing a variable with the same name of the called function (?)

Today in “Surprising Ruby”

[49] pry(main)> def f
[49] pry(main)* 1
[49] pry(main)* end
=> :f
[50] pry(main)> f
=> 1
[51] pry(main)> f = f
=> nil
[52] pry(main)> f
=> nil
[53] pry(main)> f.class
=> NilClass
[54] pry(main)> def g
[54] pry(main)* 1
[54] pry(main)* end
=> :g
[55] pry(main)> f = g
=> 1
[56] pry(main)> f
=> 1
[57] pry(main)> f.class
=> Fixnum

Does it make sense for you? I would expect f to be 1 after [51].

See also:

def foo() 'surprise'; end
foo if foo = 1

This is how ruby is, alas.

Sorry, I was a bit terse because I was on a bus at the time.

You can think of it like this:

Variables and function names occupy different namespaces (otherwise
variables would override functions, which would be bad.) The parser
in a single-pass: left-to-right, top-to-bottom. When the parser sees: `f

f, it first seesf =` so creates a slot in the variable table for ‘f’,
then when it sees the final bare ‘f’ with no other dressing, it checks
local variable table, finds a matching variable, and uses it.

To fix it, you have to make ruby not check the local variable table; for

def f
f = f()

When the parser sees ‘f()’ is knows that it must be a function (not a
variable) so only checks the function table for one called ‘f’.

Similarly, this:

def foo() 'surprise'; end
foo if foo = 1

​… results in “surprise”, because at the time the parser saw the first
foo, the only match in any of the tables was in the function table.
doesn’t get added to the variable table until the parser sees foo =

Great answer! Thanks!
El oct 20, 2014 11:56 p.m., “Matthew K.” [email protected]