Module: XKeys::Get

Included in:
Auto, Hash
Defined in:
lib/xkeys.rb

Overview

Extended fetch and get ([])

Instance Method Summary collapse

Instance Method Details

#[](*args) ⇒ Object

Perform an extended get using successive keys to traverse a tree of nested hashes and/or arrays.

key

or [range] returns the normal hash or array element (or

range-based array slice).

int1, int2

for arrays (or other objects responding to the #slice

method) returns the object’s normal two-parameter (e.g. start + length slice) index value.

key1, …, keyN[, option_hash]

traverses a tree of nested

hash- and/or array-like objects using xfetch.

Option :else => nil is used if no :else option is supplied. See xfetch for option details.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/xkeys.rb', line 94

def [] (*args)
	if args.count == 1 || (respond_to?(:slice) && args.count == 2 &&
	  args[0].is_a?(Integer) && args[1].is_a?(Integer))
 # [key] or array[start, length]
 super *args
	else
 def_opts = { :else => nil } # Default options
 if args[-1].is_a? Hash
		options, last = def_opts.merge(args[-1]), -2
 else options, last = def_opts, -1
 end
 xfetch *args[0..last], options
	end
end

#xfetch(*args) ⇒ Object

Perform an extended fetch using successive keys to traverse a tree of nested hash- and/or array-like objects.

xfetch(key1, ..., keyN [, option_hash])

Options:

:else => default value
    The default value to return if any of the keys do not exist
    (when an underlying #fetch generates a KeyError or IndexError).
    The :raise option takes precedence.

:raise => true
    Re-raise the original KeyError or IndexError if any of the keys
    do not exist. This is the default behavior for xfetch in the
    absence of an :else option.

:raise => *parameters
    Like :raise => true but does raise *parameters instead, e.g.
    :raise => RuntimeError or :raise => [RuntimeError, 'SNAFU']


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/xkeys.rb', line 61

def xfetch (*args)
	if args[-1].is_a?(Hash) then options, last = args[-1], -2
	else options, last = {}, -1
	end

	args[0..last].inject(self) do |node, key|
 begin node.respond_to?(:fetch) ? node.fetch(key) : node[key]
 rescue KeyError, IndexError
		if options[:raise] && options[:raise] != true
  raise *options[:raise]
		elsif options[:raise] || !options.has_key?(:else)
  raise
		else return options[:else]
		end
 end
	end
end