Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
share|improve this question
up vote 2 down vote accepted

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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.