executing a block in the context of receiver

M

Mark Volkmann

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

Ross Bamford

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...

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

dblack

Hi --

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 :)

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 ([email protected])
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
 
R

Ross Bamford

Hi --



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

(Oops, overzealous cut/paste job :) )

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.
 
D

dblack

Hi --

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 ([email protected])
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
 

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

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,167
Latest member
SusanaSwan
Top