[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

executing a block in the context of receiver

Mark Volkmann

3/14/2006 3:20:00 PM

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.


5 Answers

Ross Bamford

3/14/2006 3:41:00 PM

0

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

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

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



eastcoastcoder

3/15/2006 8:36:00 PM

0

Also,
send(:do_that, p3, p4)

dblack

3/15/2006 8:58:00 PM

0

Ross Bamford

3/15/2006 10:08:00 PM

0

On Thu, 2006-03-16 at 05:57 +0900, dblack@wobblini.net wrote:
> 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 :-)
>

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

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



dblack

3/15/2006 10:19:00 PM

0