Class: DottedHash
- Inherits:
-
Object
- Object
- DottedHash
- Extended by:
- ActiveModel::Naming
- Includes:
- ActiveModel::Conversion
- Defined in:
- lib/dotted_hash.rb,
lib/dotted_hash/version.rb
Overview
See Readme.md in gem/repository directory for usage instructions
Constant Summary collapse
- MAX_DEPTH =
Maximum depth of whole tree, not keys (keys depth+1). Counted from 0. Not fully bulletproof, depth may be set to wrong number if careless.
10
- MAX_ATTRS =
Maximum count of attributes. Use hash like this to specify each level. MAX_ATTRS = => 20, 2 => 5, default: 10
10
- MAX_SIZE =
Maximum size of document, counted from JSON result of document. It is not bulletproof, but if using simple structures, it is enough. Other structures may have much bigger representation in memory than in JSON.
16384
- VERSION =
"1.0"
Instance Method Summary collapse
-
#[](key) ⇒ Object
Provides access to attribute.
-
#as_json(options = nil) ⇒ Object
Returns (filtered) Ruby
Hash
with characters and objects only allowed in JSON. -
#class ⇒ Object
Let’s pretend we’re someone else in Rails.
-
#errors ⇒ Object
Standard ActiveModel Errors.
-
#id ⇒ Object
Returns
id
of document. -
#initialize(args = {}, level = 0) ⇒ DottedHash
constructor
Create new instance, recursively converting all Hashes to DottedHash and leaving everything else alone.
- #inspect ⇒ Object
-
#merge!(obj) ⇒ Object
Merge with another hash.
-
#method_missing(method_name, *arguments) ⇒ Object
Delegate method to a key in underlying hash, if present, otherwise return
nil
. - #persisted? ⇒ Boolean
-
#recursive_assign(key, value) ⇒ Object
Recursively assigns value.
-
#respond_to?(method_name, include_private = false) ⇒ Boolean
Always respond to write.
- #to_hash ⇒ Object (also: #to_h)
-
#to_json(options = nil) ⇒ Object
(also: #to_indexed_json)
JSON string of
as_json
result. -
#to_key ⇒ Object
Returns key if key exists.
-
#valid? ⇒ Boolean
Always
true
.
Constructor Details
#initialize(args = {}, level = 0) ⇒ DottedHash
Create new instance, recursively converting all Hashes to DottedHash and leaving everything else alone.
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/dotted_hash.rb', line 34 def initialize(args={}, level=0) raise ArgumentError, "Please pass a Hash-like object" unless args.respond_to?(:each_pair) raise RuntimeError, "Maximal depth reached" if level > MAX_DEPTH @depth = level @attributes = {} args.each_pair do |key, value| assign_value(key, value) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *arguments) ⇒ Object
Delegate method to a key in underlying hash, if present, otherwise return nil
.
86 87 88 89 90 91 92 93 94 |
# File 'lib/dotted_hash.rb', line 86 def method_missing(method_name, *arguments) if method_name.to_s[-1] == '=' && arguments.size == 1 attribute = method_name.to_s.chop value = arguments.first assign_value(attribute, value) else @attributes[method_name.to_sym] end end |
Instance Method Details
#[](key) ⇒ Object
Provides access to attribute. Use when you have spaces and other non a-z_
characters in attribute name.
130 131 132 |
# File 'lib/dotted_hash.rb', line 130 def [](key) @attributes[key.to_sym] end |
#as_json(options = nil) ⇒ Object
Returns (filtered) Ruby Hash
with characters and objects only allowed in JSON.
171 172 173 174 |
# File 'lib/dotted_hash.rb', line 171 def as_json(=nil) hash = to_hash hash.respond_to?(:with_indifferent_access) ? hash.with_indifferent_access.as_json() : hash.as_json() end |
#class ⇒ Object
Let’s pretend we’re someone else in Rails
184 185 186 187 188 189 190 |
# File 'lib/dotted_hash.rb', line 184 def class begin defined?(::Rails) && @attributes[:_type] ? @attributes[:_type].camelize.constantize : super rescue NameError super end end |
#errors ⇒ Object
Standard ActiveModel Errors
145 146 147 |
# File 'lib/dotted_hash.rb', line 145 def errors ActiveModel::Errors.new(self) end |
#id ⇒ Object
Returns id
of document
136 137 138 |
# File 'lib/dotted_hash.rb', line 136 def id @attributes[:id] end |
#inspect ⇒ Object
192 193 194 195 |
# File 'lib/dotted_hash.rb', line 192 def inspect s = []; @attributes.each { |k,v| s << "#{k}: #{v.inspect}" } %Q|<DottedHash#{self.class.to_s == 'DottedHash' ? '' : " (#{self.class})"} #{s.join(', ')}>| end |
#merge!(obj) ⇒ Object
Merge with another hash
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/dotted_hash.rb', line 46 def merge!(obj) if obj.respond_to? :to_h hash = obj.to_h elsif obj.respond_to? :to_hash hash = obj.to_hash else raise('Merge works only with hashlike object') end hash.each do |key, value| assign_value(key, value) end self end |
#persisted? ⇒ Boolean
140 141 142 |
# File 'lib/dotted_hash.rb', line 140 def persisted? !!id end |
#recursive_assign(key, value) ⇒ Object
Recursively assigns value. Also creates sub-DottedHashes if they don’t exist).
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/dotted_hash.rb', line 111 def recursive_assign(key, value) return nil if key.blank? keys = key.split('.') if keys.size > 1 key = keys.shift.to_sym if !@attributes[key] assign_value(key, DottedHash.new({}, @depth+1)) end sub = @attributes[key] sub.send(:recursive_assign, keys.join('.'), value) elsif keys.size == 1 assign_value(keys.shift, value) end end |
#respond_to?(method_name, include_private = false) ⇒ Boolean
Always respond to write. Respond to attribute or defined method.
99 100 101 102 103 104 105 106 |
# File 'lib/dotted_hash.rb', line 99 def respond_to?(method_name, include_private = false) # answers to any write method if method_name.to_s[-1] == '=' true else @attributes.has_key?(method_name.to_sym) || super end end |
#to_hash ⇒ Object Also known as: to_h
159 160 161 162 163 164 |
# File 'lib/dotted_hash.rb', line 159 def to_hash @attributes.reduce({}) do |sum, item| sum[ item.first ] = item.last.respond_to?(:to_hash) ? item.last.to_hash : item.last sum end end |
#to_json(options = nil) ⇒ Object Also known as: to_indexed_json
JSON string of as_json
result
177 178 179 |
# File 'lib/dotted_hash.rb', line 177 def to_json(=nil) as_json.to_json() end |
#to_key ⇒ Object
Returns key if key exists
155 156 157 |
# File 'lib/dotted_hash.rb', line 155 def to_key persisted? ? [id] : nil end |
#valid? ⇒ Boolean
Always true
150 151 152 |
# File 'lib/dotted_hash.rb', line 150 def valid? true end |