On 5/17/07, dblack / wobblini.net <dblack / wobblini.net> wrote:

> On Thu, 17 May 2007, Vasco Andrade e Silva wrote:

> > I was thinking.. If I want to "bind" self to yield context, with 0
> > params, i can use a solution like this one:
> >
> >> def create( name, &block )
> >>  person = Person.new( name )
> >>  person.instance_eval( &block )
> >>  p person
> >> end
> >
> > person.instance_eval( &block ) # some kind of yield(self) inside
> > instance_eval
> >
> > but what if i want yield with params, and still have self like

>
> That's actually what instance_exec does:
>
> # Requires Ruby 1.9
> class A
>    def x(&block)
>      instance_exec(1,2,&block)
>    end
> end

Or in Ruby 1.8.x you can use Mauricio's version:
http://eigenclass.org/hiki/bounded+space+instance_exec


> I still don't know what the rationale is for the name, or how one is
> supposed to know that instance_exec does it this way and instance_eval
> does it the other way (except that I've been using instance_eval for
> longer, but that won't help people who are just starting to learn
> Ruby).

I'm not exactly sure where the name came from. Matz mentioned it in
his RubyConf 2005 Keynote, but it seems that he got the idea, (and the
name?) from someone posting on ruby-talk  It only shows up as a
one-line item on one of his last charts.
http://glu.ttono.us/articles/2005/10/16/matzs-keynotes

_why gave an implementation here:
http://redhanded.hobix.com/inspect/aBlockCostume.html

This seems a little more naive since it always uses the same name for
the method :_cloaker, and it's not thread-safe.

ActiveSupport in Rails defines Object#instance_exec, but I'm not sure
if this was the chicken or the egg. This implementation uses a similar
technique of defining a method with the proc as the body, rails uses a
timestamp to make the method name 'unique.'


Mauricio's first implementation was a bit more sophisticated in that
it was thread-safe, but it didn't work with immediate value objects
like FixNums.

Mauricio came up with a second version which worked with these, this
version had a memory leak, leading to the latest version.

So that's the history of instance_exec as far as I've been able to
quickly ascertain.

Personally I'd prefer it if instance_exec were used to do this so that

  instance_exec(1, 2) {|a, b| ....}

would pass 1 and 2 as the arguments to the block.  Perhaps it was felt
that this would lead to confusion with the current definition which
either takes arguments (a string and optional file name and line
number) OR a block, but not both.

-- 
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/