From: Tim Pease Date: 2011-07-22T07:56:11+09:00 Subject: Re: attr_accessor for hash keys On Jul 21, 2011, at 4:41 PM, Sean O'Halpin wrote: > On Thu, Jul 21, 2011 at 10:17 PM, Chad Perrin wrote: >> Is there a way to use attr_accessor, or something like it (without >> writing it from scratch), for hash keys? For instance: >> >> class Foo >> attr_accessor :bar[:one], :bar[:two] >> def initialize(bar) >> @bar = bar >> end >> end >> >> Obviously, :bar[:one] and :bar[:two] won't work, because symbols don't >> have [] methods, but that should illustrate the general gist of what I'm >> asking (I hope). I'd just like to avoid the clutter of writing a bunch >> of basic accessors myself, the long way, in a class definition where I'd >> like to keep all the data in a hash but have direct accessor method ways >> to work with specific key=>value pairs. >> >> -- >> Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ] >> > > This is reasonably close to what you described: > > module HashAccessor > def hash_accessor(hash_name, *key_names) > key_names.each do |key_name| > define_method key_name do > instance_variable_get("@#{hash_name}")[key_name] > end > define_method "#{key_name}=" do |value| > instance_variable_get("@#{hash_name}")[key_name] = value > end > end > end > end > > class Foo > extend HashAccessor > hash_accessor :bar, :one, :two > def initialize(bar) > @bar = bar > end > end > > foo = Foo.new(:one => 1, :two => 2) # => # @bar={:one=>1, :two=>2}> > foo.one # => 1 > foo.one = 42 > foo # => # @bar={:one=>42, :two=>2}> > This sounds like a job for method_missing ... class Foo def initialize( bar ) @bar = bar end def method_missing( key, *args, &block ) super unless @bar.has_key? key @bar[key] end end Also, take a look at Ara Howard's "Map" gem and see if that will get you what you need. https://github.com/ahoward/map m = Map(:one => 1, :two => 2) s = m.struct s.one #=> 1 s.two #=> 2 Blessings, TwP