Class: SuperHash

Inherits:
Hash
  • Object
show all
Defined in:
lib/super_hash.rb

Overview

SuperHash is very much like OpenStruct except that it creates whole paths instead of just keys SuperHash is a hash whose default value defaults to another instance of SuperHash which allows for chaining:

super_hash[:x][:y][:z] will create the :x, :y, and :z sub-superhashes

Assignment creates signleton accessor methods

super_hash[:x] = 42
super_hash.respond_to? :x == true
super_hash.respond_to? :x= == true

Since a bare:

super_hash[:x]

assigns another superhash if no :x key is found, this alone results in:

super_hash.respond_to?(:x) == true
super_hash.respond_to?(:x=) == true

method_missing delegates to either :[] or :[]= (depeding on whether the method name ends with =) so either eventually results in a singleton method definition and you can use dots instead of [] like in JavaScript

super_hash.x.y.z = 42 #This creates the whole chain of hashes and the accessor methods

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ SuperHash

Returns a new instance of SuperHash.



23
24
25
26
27
# File 'lib/super_hash.rb', line 23

def initialize(*args)
  super(*args) { |hash,key|
    hash[key] = SuperHash.new
  }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(key, *args) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/super_hash.rb', line 44

def method_missing(key, *args)
  if /=$/ === key
    key = key.to_s.sub(/=$/,'').to_sym
    return public_send :[]=, key, *args
  end
  return  public_send :[], key, *args
end

Instance Method Details

#[]=(key, val) ⇒ Object

Assignment defines accessor methods



29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/super_hash.rb', line 29

def []=(key, val)
  this = self
  unless respond_to?(key)
    self.define_singleton_method(key) do
      this[key]
    end
  end
  unless respond_to?("#{key}=".to_sym)
    self.define_singleton_method("#{key}=".to_sym) do |v|
      this[key] = v
    end
  end
  return super(key, val)
end