From: Rick DeNatale Date: 2007-05-17T22:33:20+09:00 Subject: Re: self in blocks On 5/17/07, 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/