Inconsistent block parameters handling by instance_eval

class A
def A.method &block
A.new.instance_eval &block
end

def A.method2 &block
A.new.instance_eval {block.call}
end
end

A.method{p self} #prints #<A:0x28c2858>

A.method2{p self} #prints main

From this example: is instance_eval even working in method2? It clearly
shows that block is not called in A’s context.
-Patrick

On Friday 08 August 2008, Patrick Li wrote:

A.method{p self} #prints #<A:0x28c2858>

A.method2{p self} #prints main

From this example: is instance_eval even working in method2? It clearly
shows that block is not called in A’s context.
-Patrick

The effect of instance_eval is to set the variable “self” to the
receiver for
the duration of the block. In the first case, everything works as
expected. In
the second case, instead, self is changed only for the outer block,
while in
the inner block “self” remains what it were when the block was defined.
There’s nothing new here: the environment in which the block is executed
doesn’t affect its variables and the fact that instance_eval treats the
outer
block in a special way doesn’t otherwise change things.

I hope this helps

Stefano

hmmm… that makes sense.

It seems a bit counter-intuitive though. … but i guess it would have to
be this way, otherwise closures won’t work.
Thanks for the explanation Stefano.
-Patrick