Ross Bamford
3/15/2006 10:08:00 PM
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