On Tue, 30 Mar 2004, Daniel Sheppard wrote:

> I've been writing a couple of very struct-like classes, and got annoyed
> at having to write:
> 
> class MyStructLikeThing
>   attr_accessor :one, :two, :three, :four, :five
>   def initialize (one, two, three, four, five)
>     @one, @two, @three, @four, @five = one, two, three, four, five
>   end
> end
> 
> And how ugly that looked in the code, so I decided to try my hand at
> whipping up an attr_constructor statement.
> 
> class Module
>   private
>   def attr_constructor(*args)
>     self.class_eval %Q{
>       def initialize(#{args.join(', ')})
>         #{args.collect{ |setting|
> "instance_variable_set(\"@#{setting}\", #{setting})" }}
>       end
>     }
>   end
> end
> 
> class MyStructLikeThing
>   attr_accessor :one, :two, :three, :four, :five
>   attr_constructor :one, :two, :three, :four, :five
> end
> 
> It strikes me as a little cludgy. Is there a better way of doing this?
> Is there a way to get the args variable so that it can be read from
> within a module_eval block? 

i like this:


  class Foo 

    OPTIONS = :foo, :bar, :fobar
    OPTIONS.each{|opt| attr opt, true}

    def initialize arg0, arg1, opts
      @arg0, @arg1 = arg0, arg1
      opts.each{|opt, value| send "#{ opt }=", value}
    end

  end

  f = Foo.new 42, 42.0

  f = Foo.new 42, 42.0, :foo => 'forty'

  f = Foo.new 42, 42.0, :foo => 'forty',
                        :bar => 'two'

  f = Foo.new 42, 42.0, :foo     => 'forty',
                        :bar     => 'two',
                        :foorbar => 'fortytwo'

or

  class Foo 

    INIT_ARGS = :foo, :bar, :fobar
    INIT_ARGS.each{|arg| attr arg, true}

    def initialize(*args)
      INIT_ARGS.each{|arg| self.send "#{ arg }=", args.shift}
    end

  end

it's easy to extend this or make validators

-a
-- 
===============================================================================
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL     :: http://www.ngdc.noaa.gov/stp/
| TRY     :: for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done 
===============================================================================