Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why foo is not nil anymore - or function within function

Tags:

ruby

Why in below code snippet foo replaces its definition?

def foo
  def foo
    1
  end
end

for the first time foo is nil

foo
=> nil

foo.foo
=> 1

Now if I call foo again:

foo
=> 1

As you can see foo is not nil anymore. Can some one explain this to me? thanks.

like image 283
tokhi Avatar asked Dec 06 '12 16:12

tokhi


3 Answers

def foo
  p "about to redef foo"
  def foo
    1
  end
end
foo
"about to redef foo"
=> nil
foo
=> 1

Also, when you call foo.foo, it seems like you’re trying to access the inner foo method, but it doesn’t work that way. Your foo method is actually defined on Object, so you’re actually calling 1.foo.

like image 132
Josh Lee Avatar answered Nov 04 '22 07:11

Josh Lee


If you want this effect, try

def foo
  foo = proc {
    1
  }
end

Since def methods do not create a new self. Every method is bound to self, which is main in this case, an Object.new which is instantiated for every file loaded by the ruby interpreter. Inside a class, self is the class, and you get instance methods.

like image 27
Reactormonk Avatar answered Nov 04 '22 07:11

Reactormonk


Method definitions are parsed when read, but are not executed until called. When you do the first foo, the outermost foo is executed, which defines Object#foo as

def foo
  1
end

and returns nil as the return value of an operation that defined the method. From then on, when you call foo, the newly defined foo is executed, returning

1
like image 1
sawa Avatar answered Nov 04 '22 08:11

sawa