From: John Date: 2002-07-14T14:21:17+09:00 Subject: Re: instance_eval "David Alan Black" wrote in message news:Pine.LNX.4.30.0207131952450.9723-100000@candle.superlink.net... > Hi -- > > On Sun, 14 Jul 2002, John wrote: > > > Hi all, > > > > I am trying to add a method dynamically. I can do the following just fine: > > > > def create > > str = "def hello (*args) puts 'test' end" > > self.instance_eval (str) > > end > > > > This adds the hello method. But I want to pass a block to test so that it > > executes the block instead of the "puts 'test'". > > > > I tried the following after searching some previous posts: > > > > def create (&block) > > str = "def hello (*args) block.call end" > > self.instance_eval (str) > > I believe that "self.instance_eval" is essentially the same as plain > "eval", because instance_eval effectively sets the value of "self", > temporarily, to its receiver -- so setting it to "self" doesn't change > anything. (Stay tuned for others pointing out possible subtleties > that I'm overlooking :-) > > Here's a little example of switching "self" on the fly, just for > contrast: > > class Thing > def demo > puts "I am a #{type}" # => I am a Thing > s = "string" > s.instance_eval 'puts "I am a #{type}"' # => I am a String > end > end > > > end > > > > But to be honest I don't really know what I am doing there. ;-) I realize > > that instance_eval can take a block, but what name would the method be? > > I'm almost, but not quite, following your description.... Which > method do you mean? Could you explain a little more about the > context? I think there might be useful things you could do along the > lines of, maybe, a hash of Proc objects, or something like that, but > I'm not sure what the best fit would be. > > > David > > -- > David Alan Black > home: dblack@candle.superlink.net > work: blackdav@shu.edu > Web: http://pirate.shu.edu/~blackdav > > I am sorry, my examples were a little off. These should show it better. Original attempt that works but without a block parameter: def create (methodName) str = "def " + methodName + " (*args) puts 'test' end" self.instance_eval (str) end My attempt with a block: def create (methodName, &block) str = "def " + methodName + " (*args) block.call end" self.instance_eval (str) end I want to call create something like this: obj.create "newMethod" { puts "I am a new method" } obj.create "anotherMethod" { puts "I am another method" } and when I call newMethod it outputs the text "I am a new method". and when I call anotherMethod it outputs the text "I am another method". I could do this with a hash of proc objects like you suggested, but I would prefer to do it using the instance_eval method as I think its cleaner (less member variables), and I also want to learn if there is a way to associated a block with a new method and name it. I would also rather not pass a string for the method in to the create call. I want to pass a block, mainly cause I want to see how to make use of the block feature. Make sense? John.