Forum: Ruby Does instance_eval passes self as block argument?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
F1938de600a3feacd015051492fdaf0f?d=identicon&s=25 LAMBEAU Bernard (Guest)
on 2009-01-08 15:13
(Received via mailing list)
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
F1938de600a3feacd015051492fdaf0f?d=identicon&s=25 LAMBEAU Bernard (Guest)
on 2009-01-08 15:15
(Received via mailing list)
Ok, it works in Ruy 1.8.7 but not in Ruby 1.9.

Is there another way to do so?

blambeau
245a6d22816ecaeac1c9080ad183b859?d=identicon&s=25 Jan-Erik R. (Guest)
on 2009-01-08 15:16
(Received via mailing list)
LAMBEAU Bernard schrieb:
>   end
>
> 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.
245a6d22816ecaeac1c9080ad183b859?d=identicon&s=25 Jan-Erik R. (Guest)
on 2009-01-08 15:20
(Received via mailing list)
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.
F1938de600a3feacd015051492fdaf0f?d=identicon&s=25 LAMBEAU Bernard (Guest)
on 2009-01-08 15:21
(Received via mailing list)
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
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-01-08 15:45
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 }
F1938de600a3feacd015051492fdaf0f?d=identicon&s=25 LAMBEAU Bernard (Guest)
on 2009-01-08 15:54
(Received via mailing list)
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
A246f7c0ce5f2909483d358bd9e83e4e?d=identicon&s=25 Mike Gold (mikegold)
on 2009-01-08 17:51
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
F1938de600a3feacd015051492fdaf0f?d=identicon&s=25 LAMBEAU Bernard (Guest)
on 2009-01-08 18:08
(Received via mailing list)
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
A246f7c0ce5f2909483d358bd9e83e4e?d=identicon&s=25 Mike Gold (mikegold)
on 2009-01-08 18:39
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
This topic is locked and can not be replied to.