Does instance_eval passes self as block argument?

  • Thread starter LAMBEAU Bernard
  • Start date
L

LAMBEAU Bernard

Ruby's documentation of instance_eval shows the "signature" of instance_eval as:

obj.instance_eval {| | block } => obj

I assume that the block should not take any argument. However, if I
write the following code:

class A
def sayhello(who)
puts "hello #{who}: #{object_id}"
end
end

A.new.instance_eval do |who|
sayhello("me")
who.sayhello("who")
end

it prints "hello me: -605850598" then "hello who: -605850598"

Is is guaranteed to work??

blambeau
 
L

LAMBEAU Bernard

Ok, it works in Ruy 1.8.7 but not in Ruby 1.9.

Is there another way to do so?

blambeau
 
J

Jan-Erik R.

LAMBEAU said:
Ruby's documentation of instance_eval shows the "signature" of instance_eval as:

obj.instance_eval {| | block } => obj

I assume that the block should not take any argument. However, if I
write the following code:

class A
def sayhello(who)
puts "hello #{who}: #{object_id}"
end
end

A.new.instance_eval do |who|
sayhello("me")
who.sayhello("who")
end

it prints "hello me: -605850598" then "hello who: -605850598"

Is is guaranteed to work??

blambeau

should be, because it's documented. Not in the code-example but in the text:
In order to set the context, the variable self is set to obj while the
code is executing, giving the code access to obj‘s instance variables.
 
J

Jan-Erik R.

Jan-Erik R. said:
should be, because it's documented. Not in the code-example but in the
text:
In order to set the context, the variable self is set to obj while the
code is executing, giving the code access to obj‘s instance variables.
oh...sorry. I missunderstood the documentation. Instead of using a
block-parameter you can use "self" directly.
 
L

LAMBEAU Bernard

obj.instance_eval {| | block } => obj

I don't interpret it that way: it only states that self is obj inside
the block. The documentation says nothing about block arguments.

I would like something like this:

obj.instance_eval {| who| block } => obj

where who ==self == obj.

blambeau
 
B

Brian Candler

LAMBEAU said:
obj.instance_eval {| | block } => obj

I don't interpret it that way: it only states that self is obj inside
the block. The documentation says nothing about block arguments.

I would like something like this:

obj.instance_eval {| who| block } => obj
where who ==self == obj.

You can build that yourself.

class Object
def my_instance_eval(&blk)
instance_eval { blk[self] }
end
end

obj = ""
obj.my_instance_eval { |who| p who }
 
L

LAMBEAU Bernard

Sorry but it does not work:

class A
def doit(&block)
instance_eval { block[self] }
end
def sayhello(who)
puts "hello #{who}: #{object_id}"
end
end

A.new.doit do |who|
sayhello("me")
who.sayhello("who")
end

in `block in <main>': undefined method `sayhello' for main:Object
(NoMethodError)

It seems that the block is not executed in the context of A.new anymore.

I'm not sure that what I want makes sense because I've got self inside
the block, but if anyone knows how to make this code working in Ruby
1.9, I'm still interested.

blambeau


LAMBEAU said:
obj.instance_eval {| | block } => obj

I don't interpret it that way: it only states that self is obj inside
the block. The documentation says nothing about block arguments.

I would like something like this:

obj.instance_eval {| who| block } => obj
where who ==self == obj.

You can build that yourself.

class Object
def my_instance_eval(&blk)
instance_eval { blk[self] }
end
end

obj = ""
obj.my_instance_eval { |who| p who }
 
M

Mike Gold

LAMBEAU said:
I'm not sure that what I want makes sense because I've got self inside
the block, but if anyone knows how to make this code working in Ruby
1.9, I'm still interested.

class A
def doit(&block)
instance_eval(&block)
end
def sayhello(who)
puts "hello #{who}: #{object_id}"
end
end

A.new.doit do |who|
sayhello("me")
who.sayhello("who")
end

#=>
hello me: 35747370
hello who: 35747370
 
L

LAMBEAU Bernard

Works under Ruby 1.8.x, not with ruby 1.9.0 (I did not try with Ruby
1.9.1, which is more stable but not available yet under Ubuntu).

Did-you try under Ruby 1.9.1 ?

blambeau
 
M

Mike Gold

LAMBEAU said:
Works under Ruby 1.8.x, not with ruby 1.9.0 (I did not try with Ruby
1.9.1, which is more stable but not available yet under Ubuntu).

The only difference is the 'who' block parameter which is nil in 1.9.
If you really want that, this works on both 1.8 and 1.9:

class A
def doit(&block)
if RUBY_VERSION >= "1.9.0"
instance_exec(self, &block)
else
instance_eval(&block)
end
end
def sayhello(who)
puts "hello #{who}: #{object_id}"
end
end

A.new.doit do |who|
sayhello("me")
who.sayhello("who")
end
 

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

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top