Bindings and Context

P

Patrick Li

Hi,
I'm still really confused about Ruby Closures.

At first I thought closures are just blocks who "remember" the context
that they were defined in (so that they can refer to local variables and
methods)

And then I discovered instance_eval (which changes the context that a
block is evaluated in).

When you use instance_eval you can't call local methods anymore
(because, the scope has changed, and those methods aren't local
anymore).

But how come I can still use local variables?

myStr = "myString"
o = Object.new
o.instance_eval do
@str = myStr # <- why does this still work?
def method
puts @str
end
end

So are local variables sort of an exception to instance_eval? And in the
above example, how come it won't work anymore if I change myStr into an
instance variable @myStr?

Thanks a lot for helping
-Patrick

PS: Is there a detailed document I can read about OO languages? I come
from Java and I'm feeling a little lost amidst all these advanced OO
features.
 
S

Stefano Crocco

Hi,
I'm still really confused about Ruby Closures.

At first I thought closures are just blocks who "remember" the context
that they were defined in (so that they can refer to local variables and
methods)

And then I discovered instance_eval (which changes the context that a
block is evaluated in).

When you use instance_eval you can't call local methods anymore
(because, the scope has changed, and those methods aren't local
anymore).

But how come I can still use local variables?

myStr = "myString"
o = Object.new
o.instance_eval do
@str = myStr # <- why does this still work?
def method
puts @str
end
end

So are local variables sort of an exception to instance_eval? And in the
above example, how come it won't work anymore if I change myStr into an
instance variable @myStr?

instance_eval doesn't change scope. Its only effect is to change the value of
the special local variable self. This explains why you can't access instance
variables anymore: with self changed, the instance variables are instance
variables of the new self (that is, the receiver of instance_eval). The same
is true for instance methods. Local variables, on the other hand, are
unaffected by the change of self and so you can still use them.

I hope this helps

Stefano
 
P

Patrick Li

Ah. okay.
That really helps.

So is this a correct interpretation?

Every block/closure has an associated binding.

The binding can be loosely described as
-a list of local variables
-and self.

Calls to instance variables are shorthand for "self.@myInstanceVariable"
and calls to instance methods are shorthand for "self.myInstanceMethod"

Does that sound alright?
-Cuppo

PS: You've really helped me out a lot recently Stefano. Thanks a lot.
 
S

Stefano Crocco

Ah. okay.
That really helps.

So is this a correct interpretation?

Every block/closure has an associated binding.

The binding can be loosely described as
-a list of local variables
-and self.

Yes, I think so
Calls to instance variables are shorthand for "self.@myInstanceVariable"
and calls to instance methods are shorthand for "self.myInstanceMethod"

Does that sound alright?

that's perfectly correct for calls to instance methods. For instance
variables, it's true only conceptually, since ruby doesn't allow to call them
thay way.

Stefano
 
R

Robert Klemme

So is this a correct interpretation?

Every block/closure has an associated binding.

The binding can be loosely described as
-a list of local variables
-and self.
Yep.

Calls to instance variables are shorthand for "self.@myInstanceVariable"
and calls to instance methods are shorthand for "self.myInstanceMethod"

Yes, apart from access control:

robert@fussel ~
$ ruby -e 'class F;private;def x;puts 111;end
end;f=F.new;f.instance_eval { x };f.x'
111
-e:1: private method `x' called for #<F:0x1002eef4> (NoMethodError)

"private" disallows method invocation with explicit receiver.

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top