Reputation: 9339
I'm new to Ruby, so apologies if my terminology is incorrect here.
I'm trying to make a subclass of hash, but am having trouble with initialising it. I want to be able to initialise it with an existing hash, and also some additional parameters, e.g.:
x = NewHash[{:a => b}, extra_param]
I tried to do that by overriding the static Hash [] operator:
class NewHash < Hash
def self.[](hash_values, backend = nil)
@backend = backend
super(hash_values)
end
end
This doesn't work, because the [] operator is static and I can't access non-static member variables, i.e. @backend
is lost.
Is there anything I can do? The alternative is to use new
, but that doesn't give me a nice way to accept the initial hash.
Upvotes: 0
Views: 332
Reputation: 62668
This is slightly hacky, because [] isn't the hash constructor; it's a factory method. So, there's no real clean way to get private scope to the new hash.
You can do something like this:
class NewHash < Hash
def self.[](hash_values, backend = nil)
super(hash_values).tap do |hash|
hash.instance_variable_set("@backend", backend)
end
end
end
This requires the use of instance_variable_set
, which is generally considered smelly, but it works. An alternate would be to create public accessors:
class NewHash < Hash
attr_accessor :backend
def self.[](hash_values, backend = nil)
super(hash_values).tap do |hash|
hash.backend = backend
end
end
end
This, of course, is public, so if you're trying to hide it, the smellier first version might be better.
Upvotes: 1