On 2/19/06, Adam Shelly <adam.shelly / gmail.com> wrote: > The only part I don't really like is the a_init_ > sentinel I had to add to pass Koan9. Ok, after looking at some of the other solutions, I've refined my solution. It now handles multiple attributes with initializers. I think I disagree with Ara about what to do when provided with both a block and a hash. With multiple attributes, it makes more sense to me if the block acts as a default, rather than an override, so that you get the following: t = Class.new {attribute(:a,:b=>4,:c=>2){10*b+c} }.new [t.a, t.b, t.c] => [42, 4, 2] To get Ara's preferred behaviour, just add `,&block` before the `and` on the 4th line. I notice that most people extended Module, while I extended Object. Is there a reason to prefer one over the other? -Adam #-------Knowledge.rb # class Object def attribute *names, &block names.each do |name| attribute *name.map{|k,v|[k,v]} and next if name.kind_of? Hash name,v = name class_eval "def #{name};"+ "@#{name}=(defined?(@#{name}) ? @#{name} : #{name}_init_); end" class_eval "def #{name}?; !(self.#{name}.nil?); end" class_eval "def #{name}=(v); @#{name}=v; end" private; define_method("#{name}_init_", block || proc {v}) end end end