I want to make a Ruby nested hash table class to avoid repeating ugly code and to keep my programs as true to the OOP paradigm as I can. Are there any ways to make this class definition smaller and/or simpler?
To clarify, the class essentially creates an arbitrarily-deep hash table. For example, if you had a NestedHash
object called foo
, you could write foo[:a][:b][:c] = 1
.
class NestedHash
include Enumerable
def initialize
@outer = Hash.new { |hash, key| hash[key] = Hash.new(&hash.default_proc) }
end
def keys
@outer.keys
end
def values
@outer.values
end
def [](key)
@outer[key]
end
def []=(key, value)
@outer[key] = value
end
def each
@outer.each { |key, value| yield(key, value) }
end
end
1 Answer 1
So really, the meat of your whole program is in the single line of the constructor. The rest of it is just forwarding methods to @outer
. So we should do that explicitly:
require 'forwardable'
class NestedHash
extend Forwardable
include Enumerable
def_delegators :@outer, :[], :[]=, :keys, :values, :each
def initialize
@outer = Hash.new { |hash, key| hash[key] = Hash.new(&hash.default_proc) }
end
end
h = NestedHash.new
h[:a][:b] = 99
p h[:a][:b] #=> 99
Keep in mind that you can get the same effect also by just doing:
module NestedHash
def self.create
Hash.new { |hash, key| hash[key] = Hash.new(&hash.default_proc) }
end
end
and use it like:
h = NestedHash.create