Joel VanderWerf wrote in post #995632:
> Tangentially, I wonder if anything like the following (very rough proof
> of concept) has been used instead of Struct.

That's neat. However you'd have to make sure you've set a value for 
every key of interest, including defaults, before calling "structify!"

How about this variation:

class StructHash < Hash
  def initialize(h = {})
    replace(self.class::DEFAULTS.merge(h))
  end
end

def StructHash(defaults)
  k = Class.new(StructHash)
  k.const_set(:DEFAULTS, defaults)
  defaults.keys.each do |key|
    k.class_eval do
      define_method key do
        fetch key
      end
      define_method "#{key}=" do |val|
        store key, val
      end
    end
  end
  k
end

Foo = StructHash(:foo=>123, :bar=>456)
f = Foo.new(:foo=>0)
p f
p f.foo
p f.bar

I'm usually not a fan of subclassing core types, but I could be 
persuaded here.

Perhaps the initialize function should look like this instead:

class StructHash < Hash
  def initialize(h = {})
    replace(self.class::DEFAULTS)
    h.each { |k,v| send("#{k}=", v) }
  end
end

It's not as fast, but it will catch errors if you try to set 
non-existent members, and it lets you use symbols and strings 
interchangeably.

-- 
Posted via http://www.ruby-forum.com/.