Executing a block in the context of receiver

In the following code the do_this instance method of the foo object
calls yield to run the block that is passed to it.

foo.do_this(p1, p2) {
  do_that(p3, p4)
}

Is there any way to make it so that do_that is executed in the context
of the foo object, i.e. it acts as though it was invoked with
foo.do_that(p3, p4)? I know I could just say "foo.do_that(p3, p4)",
but I was wondering if I could avoid that.

···

--
R. Mark Volkmann
Object Computing, Inc.

If you're writing 'foo' then you can do:

  class Foo
    def do_this(&blk)
      instance_eval &blk
    end

    def do_that
      puts "Doing that..."
    end
  end

  f.do_this { do_that }
  # (prints) Doing that...

  # can use this form, too
  f.do_this { |foo| foo.do_that }
  # (prints) Doing that...

There's a few subtleties to using instance_eval you might want to look
up, but maybe it does the job...

···

On Wed, 2006-03-15 at 00:20 +0900, Mark Volkmann wrote:

In the following code the do_this instance method of the foo object
calls yield to run the block that is passed to it.

foo.do_this(p1, p2) {
  do_that(p3, p4)
}

Is there any way to make it so that do_that is executed in the context
of the foo object, i.e. it acts as though it was invoked with
foo.do_that(p3, p4)? I know I could just say "foo.do_that(p3, p4)",
but I was wondering if I could avoid that.

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Also,
send(:do_that, p3, p4)

Hi --

···

On Wed, 15 Mar 2006, Ross Bamford wrote:

On Wed, 2006-03-15 at 00:20 +0900, Mark Volkmann wrote:

In the following code the do_this instance method of the foo object
calls yield to run the block that is passed to it.

foo.do_this(p1, p2) {
  do_that(p3, p4)
}

Is there any way to make it so that do_that is executed in the context
of the foo object, i.e. it acts as though it was invoked with
foo.do_that(p3, p4)? I know I could just say "foo.do_that(p3, p4)",
but I was wondering if I could avoid that.

If you're writing 'foo' then you can do:

  class Foo
    def do_this(&blk)
      instance_eval &blk
    end

    def do_that
      puts "Doing that..."
    end
  end

  f.do_this { do_that }
  # (prints) Doing that...

  # can use this form, too
  f.do_this { |foo| foo.do_that }
  # (prints) Doing that...

But only if you yield self from do_this (just to clarify). And
initialize f, but I guess that was implied :slight_smile:

I like the second form better. Just having self change mysteriously
for the duration of a block always strikes me as a bit of an
obfuscation.

David

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

Hi --

>> In the following code the do_this instance method of the foo object
>> calls yield to run the block that is passed to it.
>>
>> foo.do_this(p1, p2) {
>> do_that(p3, p4)
>> }
>>
>> Is there any way to make it so that do_that is executed in the context
>> of the foo object, i.e. it acts as though it was invoked with
>> foo.do_that(p3, p4)? I know I could just say "foo.do_that(p3, p4)",
>> but I was wondering if I could avoid that.
>
> If you're writing 'foo' then you can do:
>
> class Foo
> def do_this(&blk)
> instance_eval &blk
> end
>
> def do_that
> puts "Doing that..."
> end
> end
>
> f.do_this { do_that }
> # (prints) Doing that...
>
> # can use this form, too
> f.do_this { |foo| foo.do_that }
> # (prints) Doing that...

But only if you yield self from do_this (just to clarify). And
initialize f, but I guess that was implied :slight_smile:

(Oops, overzealous cut/paste job :slight_smile: )

Probably irrelevant, but from what I can gather, instance_eval will pass
the new self in as a block parameter, too:

  Object.new.instance_eval { |me| self == me }
  # => true

Though this doesn't seem to be documented...?

I like the second form better. Just having self change mysteriously
for the duration of a block always strikes me as a bit of an
obfuscation.

I like instance_eval for those cool DSL style things, but usually I'm
with you on that one.

···

On Thu, 2006-03-16 at 05:57 +0900, dblack@wobblini.net wrote:

On Wed, 15 Mar 2006, Ross Bamford wrote:
> On Wed, 2006-03-15 at 00:20 +0900, Mark Volkmann wrote:

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Hi --

···

On Thu, 16 Mar 2006, Ross Bamford wrote:

Probably irrelevant, but from what I can gather, instance_eval will pass
the new self in as a block parameter, too:

  Object.new.instance_eval { |me| self == me }
  # => true

Though this doesn't seem to be documented...?

Interesting -- definitely relevant, too, in the sense that my
correction was wrong. I don't remember seeing that documented either.

David

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black