Bindings and Context

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.

···

--
Posted via http://www.ruby-forum.com/.

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

···

On Monday 11 August 2008, Patrick Li wrote:

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?

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.

···

--
Posted via http://www.ruby-forum.com/.

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

···

On Monday 11 August 2008, Patrick Li wrote:

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

···

On 11.08.2008 17:09, Patrick Li wrote:

Thank you Stefano.
That clears up a lot of my misconceptions.
  -Patrick

···

--
Posted via http://www.ruby-forum.com/.