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 ===============================================================================