Hi --

On Wed, 20 Dec 2006, 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

Here's one way:

   class Base
     class << self
       def enhance(*attributes)
         attr_accessor *attributes
         define_method(:initialize) do |*args|
           args.each_with_index {|a,i| send("#{attributes[i]}=", a) }
         end
       end
     end
   end


David

-- 
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
    aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)