From: list-bounce / example.com [mailto:list-bounce / example.com] On Behalf Of
Emmanuel Oga
Sent: Wednesday, September 26, 2007 2:51 AM
>
>Hi! thanks for you replies. I'm going to analyze them. For the moment i
>wanted to answer the question of the unnatural api. The reason i wan't
>to do it that way is because i'm not going to use String or array for
>most of the options, but Structs. So i want a way to let the user do
>this
>
>Struct.new "Value", :sub1, :sub2, :sub3 << In fact, the user may not
>even know about the Struct::Value class.
>
>class Options
>...same as before...
>define_option :an_option
>end
>
>opt= Options.new
>
>opt.an_option do |o|
>o.sub1= ...
>o.sub2= ...
>o.sub3= ...
>end
>
>instead of
>
>an_option.sub1= ...
>an_option.sub2= ...
>an_option.sub3= ...
>--

Acceptable explanation. Then, trying to answer:

1. Defining the method you need "by hands":

class Option
  def an_option
    @an_option ||= Value.new
    yield @an_option if block_given?
    @an_option
  end
end

2. Designing #define_option

class Option
  def self.define_option(name, type)
     class_eval %Q{
      def #{name}
        @#{name} ||= #{type.inspect}.new
        yield @#{name} if block_given?
        @#{name}
      end
     }
  end

  define_option :an_option, Array
end

o = Option.new

p o.an_option # => []

o.an_option { |opt|
  opt << 1 << 2 << 3
}

p o.an_option # => [1,2,3]

Really, I think it can be done with more grace (without textual eval).

V.