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.
On Thu, Jul 21, 2011 at 10:17 PM, Chad P. [email protected] wrote:
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 P. [ 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) # => #<Foo:0x9c28310
@bar={:one=>1, :two=>2}>
foo.one # => 1
foo.one = 42
foo # => #<Foo:0x9c28310
@bar={:one=>42, :two=>2}>
Regards,
Sean
On Jul 21, 2011, at 4:41 PM, Sean O’Halpin wrote:
end
end
foo = Foo.new(:one => 1, :two => 2) # => #<Foo:0x9c28310
@bar={:one=>1, :two=>2}>
foo.one # => 1
foo.one = 42
foo # => #<Foo:0x9c28310
@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.
m = Map(:one => 1, :two => 2)
s = m.struct
s.one #=> 1
s.two #=> 2
Blessings,
TwP
On Thu, Jul 21, 2011 at 4:17 PM, Chad P. [email protected] wrote:
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 P. [ original content licensed OWL: http://owl.apotheon.org ]
You could coerce forwardable into kind of behaving like this:
require ‘forwardable’
class Foo
extend Forwardable
def_delegator ‘@bar’, ‘[], :one’, ‘one’
def_delegator ‘@bar’, ‘[], :two’, ‘two’
def initialize(bar)
@bar = bar
end
end
foo = Foo.new one: 1, two: 2
foo.one # => 1
foo.two # => 2
But if they ever change its implementation, this will break >.<
Honestly, I’d probably do what Sean did.
Tim P. wrote in post #1012284:
This sounds like a job for method_missing …
In which case, you might as well just use OpenStruct.
require ‘ostruct’
=> true
os = OpenStruct.new :foo=>1, :bar=>2
=> #
os.foo
=> 1
os.bar
=> 2
Chad P. wrote in post #1012264:
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.
irb(main):001:0> Foo = Struct.new :one, :two
=> Foo
irb(main):002:0> f = Foo.new
=> #
irb(main):003:0> f[:one]
=> nil
irb(main):004:0> f[:one] = 1
=> 1
irb(main):005:0> f.one
=> 1
irb(main):006:0> f.one = 111
=> 111
irb(main):007:0> f[:one]
=> 111
irb(main):008:0> Hash[*f.members.zip(f.to_a).flatten]
=> {:one=>111, :two=>nil}
irb(main):009:0> class Struct
irb(main):010:1> def to_hash;Hash[*members.zip(to_a).flatten];end
irb(main):011:1> end
=> nil
irb(main):012:0> f.to_hash
=> {:one=>111, :two=>nil}
Kind regards
robert
On Fri, Jul 22, 2011 at 06:17:36AM +0900, Chad P. wrote:
Is there a way to use attr_accessor, or something like it (without
writing it from scratch), for hash keys?
Judging by the responses, the answer is basically “no”. I appreciate
the
work-around examples, though; some of them are pretty interesting, and
I’ll make use of (one of?) them.
Thanks for the responses.
Brian C. wrote in post #1012394:
Tim P. wrote in post #1012284:
This sounds like a job for method_missing …
In which case, you might as well just use OpenStruct.
require ‘ostruct’
=> true
os = OpenStruct.new :foo=>1, :bar=>2
=> #
os.foo
=> 1
os.bar
=> 2
im new to this. i was wondering if the tutorial in try ruby is usefull
and worth the time.i use to do turbo c