The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Ruby instance_exec aka instance_eval with parameters

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Jay Fields

Posts: 765
Nickname: jayfields
Registered: Sep, 2006

Jay Fields is a software developer for ThoughtWorks
Ruby instance_exec aka instance_eval with parameters Posted: Sep 8, 2006 4:32 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Jay Fields.
Original Post: Ruby instance_exec aka instance_eval with parameters
Feed Title: Jay Fields Thoughts
Feed URL: http://blog.jayfields.com/rss.xml
Feed Description: Thoughts on Software Development
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Jay Fields
Latest Posts From Jay Fields Thoughts

Advertisement
Recently we were extracting some common behavoir to a class method. The behavior of the methods being defined was similar; however, it did differ slightly so we needed the ability to pass a block to the method. Unfortunately, we needed the block to take a parameter and also execute in the scope of the instance.

For example, the bubble method from my previous example is used to define methods dynamically. We also needed the bubble method to add a string to an array.
class << Object
def bubble(*args, &block)
args.each do |method_name|
define_method(method_name) do
instance_eval(&block) if block_given?
self
end
end
end
end
The above implementation will work for this code:
class Foo
bubble :return_self do
some_array << 'return_self'
end
bubble :return_self2 do
some_array << 'return_self2'
end
end
However, if you could pass a parameter to the block the code could become:
class Foo
bubble :return_self do |method_name|
some_array << method_name.to_s
end
end
Unfortunately, instance_eval does not currently allow you to pass parameters.

In Ruby 1.9 instance_exec should solve this problem; however, for the time being you can find an implementation for 1.8.4 that was written by Mauricio Fernandez.
  def instance_exec(*args, &block)
mname = "__instance_exec_#{Thread.current.object_id.abs}"
metaclass.class_eval{ define_method(mname, &block) }
begin
ret = send(mname, *args)
ensure
metaclass.class_eval{ undef_method(mname) } rescue nil
end
ret
end

def metaclass
class << self
self
end
end
Using instance_exec allows us to use this implementation for bubble:
class << Object
def bubble(*args, &block)
args.each do |method_name|
define_method(method_name) do
instance_exec(method_name, &block) if block_given?
self
end
end
end
end
This allows us to dry up the Foo code to be:
class Foo
bubble :return_value1, :return_value2 do |method_name|
some_array << method_name
end
end
For more info on instance_exec in Ruby 1.9 check out Mauricio's write-up.

Read: Ruby instance_exec aka instance_eval with parameters

Topic: call_stack 0.1.0: making ruby-breakpoint/Rails' breakpointer work with Ruby 1.8.5 Previous Topic   Next Topic Topic: Cheat Sheet: Subversion + Rails + Dreamhost

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use