How does top level method is being called Inside the block with instance_eval?

Hi,

Follow the code below :

class Foo
def initialize
@var = 1
end

private

def bar
11
end
end

p foo = Foo.new # #<Foo:0x1fc41f0 @var=1>

def baz;13;end

foo.instance_eval do
p self # #<Foo:0x1fc41f0 @var=1>
p bar # 11
p @var # 1
p baz # 13
end

Now foo.instance_eval set self as foo. Then how the call to method
baz is allowed inside the block? What is the theory behind it?

On Mon, Oct 28, 2013 at 4:21 PM, Love U Ruby [email protected]
wrote:

p self # #<Foo:0x1fc41f0 @var=1>
p bar # 11
p @var # 1
p baz # 13
end

Now foo.instance_eval set self as foo. Then how the call to method
baz is allowed inside the block? What is the theory behind it?

It’s because methods defined in the top level end up being defined as
private methods of Object, and as all classes in the end inherit from
object, you can call that method from within any instance of any
object:

2.0.0-p195 :001 > s = “1234”
=> “1234”
2.0.0-p195 :002 > def foo; puts “this is foo”; end
=> nil2.0.0-p195 :004 > s.instance_eval {foo}
this is foo
2.0.0-p195 :009 > Object.private_methods.grep(/foo/)
=> [:foo]
2.0.0-p195 :010 > String.private_methods.grep(/foo/)
=> [:foo]

Jesus.

“Jesús Gabriel y Galán” [email protected] wrote in post
#1125896:

On Mon, Oct 28, 2013 at 4:21 PM, Love U Ruby [email protected]

It’s because methods defined in the top level end up being defined as
private methods of Object, and as all classes in the end inherit from
object, you can call that method from within any instance of any
object:

Thanks for your answer. How would you explain in case of local variables
:

class Foo
def initialize
@var = 1
end

private

def bar
11
end
end

foo = Foo.new # #<Foo:0x1fc41f0 @var=1>

baz = 2

foo.instance_eval do
p baz # 2 <- why not error?
end

On Mon, Oct 28, 2013 at 4:44 PM, Love U Ruby [email protected]
wrote:

:
end
end

foo = Foo.new # #<Foo:0x1fc41f0 @var=1>

baz = 2

foo.instance_eval do
p baz # 2 <- why not error?
end

Because blocks (do…end) are closures and have access to their
surrounding scope. instance_eval is just a regular method to which a
block is passed, no new scope is created. This is in contrast to some
keywords like def or class, which create a new scope that is not a
closure.

Jesus.

unsubscribe

2013/10/28 Jess Gabriel y Galn [email protected]

“Jesús Gabriel y Galán” [email protected] wrote in post
#1125900:

On Mon, Oct 28, 2013 at 4:44 PM, Love U Ruby [email protected]

Because blocks (do…end) are closures and have access to their
surrounding scope. instance_eval is just a regular method to which a
block is passed, no new scope is created. This is in contrast to some
keywords like def or class, which create a new scope that is not a
closure.

Excellent!

class Foo
def initialize
@var = 1
end

private

def bar
11
end
end

foo = Foo.new # #<Foo:0x1fc41f0 @var=1>

@x,@@y = 10,11

foo.instance_eval do
p @x # nil # why nil ?
p @@y # 11 # why not nil ?
end

On Mon, Oct 28, 2013 at 5:00 PM, Love U Ruby [email protected]
wrote:

Excellent!
end
end

foo = Foo.new # #<Foo:0x1fc41f0 @var=1>

@x,@@y = 10,11

foo.instance_eval do
p @x # nil # why nil ?
p @@y # 11 # why not nil ?
end

Variables that start with @ are instance variables. Instance variables
belong to the instance where they are assigned a value. In this case,
@x is defined in the top level, so it belongs to the top level object
only, the one “called” main. You cannot see it from anywhere else and
is not related to the inheritance or anything like that. When you call
instance_eval, self is set to the instance it is being called on, in
this case foo, so @x is looked up in that object, where it doesn’t
exist, so it’s nil.

On the other hand, variables that start with @@ are class variables,
and are inherited by all subclasses. The class variable @@y defined in
the top level scope ends up being defined in Object:

2.0.0-p195 :001 > @@y = 11
(irb):1: warning: class variable access from toplevel
=> 11
2.0.0-p195 :002 > Object.class_variables
=> [:@@y]

so it’s accessible from any subclass of Object (basically any object):

2.0.0-p195 :021 > class Foo
2.0.0-p195 :022?> def y
2.0.0-p195 :023?> @@y
2.0.0-p195 :024?> end
2.0.0-p195 :025?> end
=> nil
2.0.0-p195 :026 > Foo.new.y
=> 11

Jesus.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs