Something like thie following should work:
require 'test/unit'
include Test::Unit::Assertions
class Base
class << self
def enhance(*attributes)
attr_accessor *attributes
define_method(:initialize) do |*ary|
attributes.each do |a|
send(a.to_s + "=", ary.shift)
end
end
end
end
end
class Derived < Base; end
class Testing < Test::Unit::TestCase
def test_initialize
Derived.enhance(:a, :b, :c)
d = Derived.new("a", "b", "c")
assert_equal "a", d.a
assert_equal "b", d.b
assert_equal "c", d.c
end
end
I didn't really do what you want, because I'm not actually using class_eval here at all, but the assertions pass, anyway, which I assume is the real goal.
Note that I'm using attr_accessor here instead of attr_reader, because it's much easier to set the attributes this way. You could just about as easily use instance_variable_set or whatever the method is, but I prefer this for my own code.
Note also that if you call enhance() multiple times on the same class, you'll recreate the initialize() method each time, which is probaby a bad thing; as long as this is just for testing, you should be fine, but I'd be wary of putting this into production anywhere.
One of the things I love about ruby is I can usually use a block instead of a string with the eval methods, but what I love even more is being able to skip the eval methods entirely.
···
On Dec 19, 2006, at 2:47 PM, Mariano Kamp wrote:
Hi,
given the following contrived example I am wondering how to use a block with class_eval instead of using the string like in the code below?!
Any ideas?
Cheers,
Mariano
require 'test/unit'
include Test::Unit::Assertions
class Base
class << self
def enhance(*attributes)
class_eval do
attr_reader *attributes
end
initializer = "def initialize(#{attributes.join(", ")})"
attributes.each {|a| initializer << "@#{a}=#{a}\n"}
initializer << "end"
# ------
class_eval initializer # <-------
# ------
end
end
end
class Derived < Base; end
Derived.enhance(:a, :b, :c)
d = Derived.new("a", "b", "c")
assert_equal "a", d.a
assert_equal "b", d.b
assert_equal "c", d.c
--
Some people are afraid of heights. I'm afraid of widths.
-- Stephen Wright
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com