1

It's just redundant having to initialize the child element all the time. What I meant was this:

@parent = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }

if I try to create another multi-dimensional node, I try coding:

@parent[:child][some_field] = "Some example data..."

I am always getting this error:

undefined method `[]=' for nil:NilClass (NoMethodError)

Do you have any ideas how to solve this?

Bajongskie
  • 453
  • 2
  • 9
  • 22
  • This works for me: `parent = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }; parent[:child][:some_field] = 4`. Can you give us more precise steps to reproduce the problem? – Damiano Stoffie Dec 12 '15 at 12:14
  • What do you have as `default_proc`? – sawa Dec 12 '15 at 12:29
  • What Ruby version do you use? – spickermann Dec 12 '15 at 12:33
  • The constructor for the hash is correct, what I suspect is that something like `@parent[:child] = nil` happens somewhere in the code – Damiano Stoffie Dec 12 '15 at 12:34
  • I think you're right. The configurations are correct, and after a bit of testing, I found the culprit. It turns out that the @parent example above doesn't use the Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) } instead, an object from simple_xlsx_reader. The app I'm building is a generator, where if no parameters are found, will use the given example above. – Bajongskie Dec 12 '15 at 13:11
  • See also http://stackoverflow.com/questions/5878529/how-to-assign-hashab-c-if-hasha-doesnt-exist – Paul Schreiber Dec 12 '15 at 13:17

2 Answers2

3

I you need nested hashes more offen, why don't you define your own class?

class NestedHash < Hash  
  def initialize
    super { |h,k| h[k] = Hash.new(&h.default_proc) }
  end
end

h = NestedHash.new
h[:foo][:bar] = :baz
h[:foo][:bar] #=> :baz
spickermann
  • 100,941
  • 9
  • 101
  • 131
2

Somewhat similar to spickermann's answer, but a little different.

class MyHash < Hash
  def initialize
    self.default_proc = proc{|h, k| h[k] = MyHash.new}
  end
end

@parent = MyHash.new

Note that there is no need to pass arguments/block to MyHash.new as setting a different default would defeat the purpose of using MyHash, and Hash would be better suited in such case.

sawa
  • 165,429
  • 45
  • 277
  • 381