Module: XKeys::Set_

Included in:
Set_Auto, Set_Hash
Defined in:
lib/xkeys.rb

Overview

“Private” module for XKeys::Set_* common code

Instance Method Summary collapse

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 :[].



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/xkeys.rb', line 187

def _xkeys_new (key2, info, options)
	if respond_to? :xkeys_new
 # Note: #xkeys_new is responsible for cloning extensions
 # as desired or needed.
 xkeys_new key2, info, options
	else
 node = info[:block].call(key2, options) ? [] : {}

 # 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.

Options:

:[] => false
    Disable :[] push mode


141
142
143
144
145
146
147
148
149
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
# File 'lib/xkeys.rb', line 141

def _xkeys_set (*args, &block)
	if args[-2].is_a?(Hash) then options, last = args[-2], -3
	else options, last = {}, -2
	end

	push_mode = options[:[]] != false

	if args.count + last == 0
 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 }, options)
  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 }, options)
  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.
 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