Class: Yagni::Hash
- Inherits:
-
Object
- Object
- Yagni::Hash
- Defined in:
- lib/yagni/hash.rb
Overview
Yagni::Hash is a class that provides easy access to members, in a method-like syntax.
Usage:
h = Yagni::Hash.new({ :my => 'hash',
:is => { :just => 'awesome!' }
})
h.my #=> "hash"
h.is.just #=> "awesome!"
You can also pass a block with your data, allowing us to give you a method-like access syntax, as long as you provide us the corresponding hash. The code passed in initialization will only be called when you first try to access a key.
# File: data.json
{
"my": "json",
"is": {
"just": "awesome!"
}
}
# File: test.rb
require 'json'
require 'yagni'
y = Yagni::Hash.new { JSON.parse File.read('data.json') }
y.my #=> "json"
# You need to call Yagni::Hash#reload, otherwise we would have to
# monkey patch Object::Hash, and that would be terrible!
y.reload #=> true
y.is.just #=> "awesome!"
Instance Method Summary collapse
-
#change_context_to(key) ⇒ Object
Updates the current context and symbolize its keys.
-
#initialize(hash = nil, &block) ⇒ Hash
constructor
Creates a new Yagni::Hash instance.
-
#load_data ⇒ Object
Calls the passed block on initialization (which should provide us the data).
-
#method_missing(meth, *args, &block) ⇒ Object
If the method passed is a key from the current context, we return it.
-
#nested?(obj) ⇒ Boolean
Checks wheter the given object is another hash (as in Object::Hash).
-
#reload ⇒ Object
reloads the object.
-
#respond_to?(name) ⇒ Boolean
Updates respond_to? so that we answer
true
for key names. -
#setup_context ⇒ Object
Symbolizes our data and make a copy of it as the current context.
-
#symbolize_keys!(hash) ⇒ Object
Converts all the keys of the passed hash to symbols.
Constructor Details
#initialize(hash = nil, &block) ⇒ Hash
Creates a new Yagni::Hash instance. You can pass it an Object::Hash instance directly, or a code block, which will return our hash. The data will be lazily initialized, meaning that the block will be only called when you first try to access a key.
47 48 49 50 51 52 53 54 55 |
# File 'lib/yagni/hash.rb', line 47 def initialize(hash=nil, &block) @data = @context = hash setup_context if @context @loader = block @loaded = !block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object
If the method passed is a key from the current context, we return it. Otherwise, self
is returned so that the user can chain keys in a method-like syntax.
66 67 68 69 70 71 72 73 74 |
# File 'lib/yagni/hash.rb', line 66 def method_missing(meth, *args, &block) load_data unless @loaded return change_context_to(meth) && self if nested? @context[meth] return change_context_to(meth) if @context[meth] super end |
Instance Method Details
#change_context_to(key) ⇒ Object
Updates the current context and symbolize its keys.
108 109 110 111 112 113 |
# File 'lib/yagni/hash.rb', line 108 def change_context_to(key) @context = @context[key] symbolize_keys!(@context) if nested? @context @context end |
#load_data ⇒ Object
Calls the passed block on initialization (which should provide us the data)
78 79 80 81 82 83 84 |
# File 'lib/yagni/hash.rb', line 78 def load_data @data = @loader.call symbolize_keys! @data @loaded = true @context = @data.dup end |
#nested?(obj) ⇒ Boolean
Checks wheter the given object is another hash (as in Object::Hash)
103 104 105 |
# File 'lib/yagni/hash.rb', line 103 def nested?(obj) obj && obj.kind_of?(Object::Hash) end |
#reload ⇒ Object
reloads the object. In other words, we change the context to the root of the initial data.
97 98 99 100 |
# File 'lib/yagni/hash.rb', line 97 def reload @context = @data true end |
#respond_to?(name) ⇒ Boolean
Updates respond_to? so that we answer true
for key names
58 59 60 61 |
# File 'lib/yagni/hash.rb', line 58 def respond_to?(name) return true if @data && (@data.key?(name.to_s) || @data.key?(name.to_sym)) super end |
#setup_context ⇒ Object
Symbolizes our data and make a copy of it as the current context
116 117 118 119 |
# File 'lib/yagni/hash.rb', line 116 def setup_context symbolize_keys! @data @context = @data.dup end |
#symbolize_keys!(hash) ⇒ Object
Converts all the keys of the passed hash to symbols.
87 88 89 90 91 92 93 |
# File 'lib/yagni/hash.rb', line 87 def symbolize_keys!(hash) hash.keys.each do |key| hash[key.to_sym] = hash.delete(key) end hash end |