Module: XKeys::Set_
Overview
“Private” module for XKeys::Set_* common code
Instance Method Summary collapse
-
#_xkeys_new(key2, info, options) ⇒ Object
Return a new node for node suitable to hold key2.
-
#_xkeys_set(*args, &block) ⇒ Object
Common code for XKeys::Set_Hash and XKeys::Set_Auto.
Instance Method Details
#_xkeys_new(key2, info, options) ⇒ Object
Return a new node for node suitable to hold key2. Either key1 or key2 (or both) may be :[].
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/xkeys.rb', line 200 def _xkeys_new (key2, info, ) if respond_to? :xkeys_new # Note: #xkeys_new is responsible for cloning extensions # as desired or needed. xkeys_new key2, info, else node = info[:block].call(key2, ) ? [] : {} # Clone XKeys extensions from the root node node.extend XKeys::Get if is_a? XKeys::Get node.extend XKeys::Set_Auto if is_a? XKeys::Set_Auto node.extend XKeys::Set_Hash if is_a? XKeys::Set_Hash node end end |
#_xkeys_set(*args, &block) ⇒ Object
Common code for XKeys::Set_Hash and XKeys::Set_Auto. This method returns true if it is handling the set, or false if the caller should super to handle the set.
_xkeys_set(key1, ..., keyN[, option_hash], value) { |key, options| block }
If the root of the tree responds to the #xkeys_new method, it will be called as follows whenever a new node needs to be created:
xkeys_new(key2, info_hash, option_hash)
where info_hash contains
:node => The current node
:key1 => The key in the current node, or :[]
:block => The block passed to _xkeys_set
The returned new node will be assigned to node (or pushed onto the end of the array) and should be appropriate to accept key2.
Otherwise, the block should return true for array-like keys or false for hash-like keys. An array or hash node will be added accordingly.
If a key is :[], the current node responds to the #push method, and push mode has not been disabled (see below), a new node will be pushed onto the end of the current node.
If the root of the tree responds to the #xkeys_on_final method, it will be called as follows before the (final leaf) assignment:
xkeys_on_final(leaf_node, key, value, option_hash)
Options:
:[] => false
Disable :[] push mode
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/xkeys.rb', line 150 def _xkeys_set (*args, &block) if args[-2].is_a?(Hash) then , last = args[-2], -3 else , last = {}, -2 end push_mode = [:[]] != false if args.count + last == 0 xkeys_on_final self, args[0], args[-1], if respond_to? :xkeys_on_final if args[0] == :[] && push_mode && respond_to?(:push) push args[-1] # array[:[]] = value true # done--don't caller-super else false # use caller-super to do it end else # root[key1, ..., keyN[, option_hash]] = value (node, key) = args[1..last].inject([self, args[0]]) do |nk1, k2| if nk1[1] == :[] && push_mode && nk1[0].respond_to?(:push) # Push a new node onto an array-like node node = _xkeys_new(k2, { :node => nk1[0], :key1 => nk1[1], :block => block }, ) nk1[0].push node [node, k2] elsif nk1[0][nk1[1]].nil? # Auto-vivify the specified key/index node = _xkeys_new(k2, { :node => nk1[0], :key1 => nk1[1], :block => block }, ) nk1[0][nk1[1]] = node [node, k2] else # Traverse an existing node [nk1[0][nk1[1]], k2] end end # Assign (or push) according to the final key. xkeys_on_final node, args[0], args[-1], if respond_to? :xkeys_on_final if key == :[] && push_mode && node.respond_to?(:push) node.push args[-1] else node[key] = args[-1] end true # done--don't caller-super end end |