Does instance_eval passes self as block argument?

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

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

Is there another way to do so?

blambeau

···

On Thu, Jan 8, 2009 at 3:12 PM, LAMBEAU Bernard <blambeau@gmail.com> wrote:

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

LAMBEAU Bernard schrieb:

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.

Jan-Erik R. schrieb:

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.

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

···

On Thu, Jan 8, 2009 at 3:15 PM, Jan-Erik R. <badboy@heartofgold.co.cc> wrote:

LAMBEAU Bernard schrieb:

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.

LAMBEAU Bernard wrote:

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 }

···

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

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

···

On Thu, Jan 8, 2009 at 3:44 PM, Brian Candler <b.candler@pobox.com> wrote:

LAMBEAU Bernard wrote:

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 }
--
Posted via http://www.ruby-forum.com/\.

LAMBEAU Bernard wrote:

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

···

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

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

···

On Thu, Jan 8, 2009 at 5:51 PM, Mike Gold <mike.gold.4433@gmail.com> wrote:

LAMBEAU Bernard wrote:

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
--
Posted via http://www.ruby-forum.com/\.

LAMBEAU Bernard wrote:

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

···

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