Class: Clive::StructHash

Inherits:
Object
  • Object
show all
Defined in:
lib/clive/struct_hash.rb

Overview

A Struct-like Hash (or Hash-like Struct)

sh = StructHash.new(:a => 1)
sh.a       #=> 1
sh[:a]     #=> 1

sh.set 42, [:answer, :life]
sh.answer  #=> 42
sh.life    #=> 42

sh.to_h
#=> {:a => 1, :answer => 42}
sh.to_struct('Thing')
#=> #<struct Struct::Thing @a=1 @answer=42>

Instance Method Summary collapse

Constructor Details

#initialize(kvs = {}) ⇒ StructHash

Returns a new instance of StructHash.



27
28
29
30
# File 'lib/clive/struct_hash.rb', line 27

def initialize(kvs={})
  @data = kvs
  @aliases = Hash[ kvs.map {|k,v| [k, k] } ]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args, &block) ⇒ Object

Checks whether the method corresponds to a key, if so gets the value. Checks whether the method ends with ‘?’, then checks if the key exists. Otherwise calls super.



88
89
90
91
92
93
94
95
96
# File 'lib/clive/struct_hash.rb', line 88

def method_missing(sym, *args, &block)
  if key?(sym)
    fetch sym
  elsif sym.to_s[-1..-1] == "?"
    key? sym.to_s[0..-2].to_sym
  else
    super sym, *args, &block
  end
end

Instance Method Details

#==(other) ⇒ Object



104
105
106
# File 'lib/clive/struct_hash.rb', line 104

def ==(other)
  to_h == other.respond_to?(:to_h) ? other.to_h : other
end

#__respond_to?Object



20
# File 'lib/clive/struct_hash.rb', line 20

alias_method :__respond_to?, :respond_to?

#dataHash

Returns The data without the :args key.

Returns:

  • (Hash)

    The data without the :args key.



62
63
64
# File 'lib/clive/struct_hash.rb', line 62

def data
  @data.reject {|k,v| k == :args }
end

#fetch(key) ⇒ Object Also known as: []

Gets the value from the StructHash corresponding to the key given.

Parameters:

  • key (Symbol)


51
52
53
# File 'lib/clive/struct_hash.rb', line 51

def fetch(key)
  @data.fetch @aliases[key]
end

#key?(key) ⇒ Boolean

Checks whether the StructHash contains an entry for the key given.

Returns:

  • (Boolean)


57
58
59
# File 'lib/clive/struct_hash.rb', line 57

def key?(key)
  @aliases.key? key
end

#respond_to?(sym, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
101
102
# File 'lib/clive/struct_hash.rb', line 98

def respond_to?(sym, include_private=false)
  return true if key?(sym)
  return true if sym.to_s[-1..-1] == "?" && key?(sym.to_s[0..-2].to_sym)
  return __respond_to?(sym, include_private)
end

#store(keys, val) ⇒ Object

Sets a value in the StructHash, this can be set with multiple keys but the first will be set as the most important key, the others will not show up in #to_h or #to_struct.

Parameters:

  • keys (#to_sym, Array<#to_sym>)
  • val


38
39
40
41
42
43
44
45
46
# File 'lib/clive/struct_hash.rb', line 38

def store(keys, val)
  keys = Array(keys).map(&:to_sym)

  keys.each do |key|
    @aliases[key] = keys.first
  end

  @data[keys.first] = val
end

#to_hHash Also known as: to_hash

Returns a hash representation of the StructHash instance, using only the important keys. This acts recursively, so any contained StructHashes will have #to_h called on them.

Returns:

  • (Hash)


71
72
73
# File 'lib/clive/struct_hash.rb', line 71

def to_h
  Hash[ data.map {|k,v| v.is_a?(StructHash) ? [k, v.to_h] : [k, v] } ]
end

#to_struct(name = nil) ⇒ Struct

Returns a struct representation of the StructHash instance, using only the important keys. This does not modify any contained StructHash instances like #to_h, but leaves them as they are.

Returns:

  • (Struct)


81
82
83
# File 'lib/clive/struct_hash.rb', line 81

def to_struct(name=nil)
  Struct.new(name, *data.keys).new *data.values
end