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
local
variables would override functions, which would be bad.) The parser
works
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
the
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
example:

def f
  1
end
f = f()

When the parser sees ‘f()’ is knows that it must be a function (not a
local
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.
One
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]
escribió: