Module: MoreCoreExtensions::Shared::Nested
- Included in:
- ArrayNested, ArrayNested, HashNested, HashNested
- Defined in:
- lib/more_core_extensions/core_ext/shared/nested.rb
Instance Method Summary collapse
-
#deep_clone ⇒ Object
Create a deep clone of the object.
-
#delete_path(*args) ⇒ Object
Delete the value at the specified nesting.
-
#fetch_path(*args) ⇒ Object
Fetch the value at the specific nesting.
-
#find_path(val) ⇒ Object
Detect which nesting holds the specified value.
-
#has_key_path?(*args) ⇒ Boolean
(also: #include_path?, #key_path?, #member_path?)
Check if a key exists at the specified nesting.
-
#store_path(*args) ⇒ Object
Store a value at the specified nesting.
Instance Method Details
#deep_clone ⇒ Object
Create a deep clone of the object. This is similar to deep_dup but uses a Marshal based approach instead.
h1 = {:a => "hello"}
h2 = h1.deep_clone
h1[:a] << " world"
h1[:a] # "hello world"
h2[:a] # "hello"
115 116 117 |
# File 'lib/more_core_extensions/core_ext/shared/nested.rb', line 115 def deep_clone Marshal.load(Marshal.dump(self)) end |
#delete_path(*args) ⇒ Object
Delete the value at the specified nesting
7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/more_core_extensions/core_ext/shared/nested.rb', line 7 def delete_path(*args) args = args.first if args.length == 1 && args.first.kind_of?(Array) raise ArgumentError, "must pass at least one key" if args.empty? key = args.first raise ArgumentError, "must be a number" if self.kind_of?(Array) && !key.kind_of?(Numeric) child = self[key] if args.length == 1 || !child.respond_to?(:delete_path) self.kind_of?(Array) ? self.delete_at(key) : self.delete(key) else child.delete_path(args[1..-1]) end end |
#fetch_path(*args) ⇒ Object
Fetch the value at the specific nesting
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/more_core_extensions/core_ext/shared/nested.rb', line 25 def fetch_path(*args) args = args.first if args.length == 1 && args.first.kind_of?(Array) raise ArgumentError, "must pass at least one key" if args.empty? result = self args.each_with_index do |key, i| raise ArgumentError, "must be a number" if result.kind_of?(Array) && !key.kind_of?(Numeric) result = result[key] if !result.respond_to?(:fetch_path) && (i + 1) != args.size result = nil break end end result end |
#find_path(val) ⇒ Object
Detect which nesting holds the specified value
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/more_core_extensions/core_ext/shared/nested.rb', line 93 def find_path(val) self.each_with_index do |v, k| k, v = v if self.kind_of?(Hash) return [k] if v == val c = v.respond_to?(:find_path) ? v.find_path(val) : [] return c.unshift(k) unless c.blank? end [] end |
#has_key_path?(*args) ⇒ Boolean Also known as: include_path?, key_path?, member_path?
Check if a key exists at the specified nesting
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/more_core_extensions/core_ext/shared/nested.rb', line 45 def has_key_path?(*args) args = args.first if args.length == 1 && args.first.kind_of?(Array) raise ArgumentError, "must pass at least one key" if args.empty? key = args.first raise ArgumentError, "must be a number" if self.kind_of?(Array) && !key.kind_of?(Numeric) has_child = self.kind_of?(Array) ? self.includes_index?(key) : self.has_key?(key) return has_child if args.length == 1 child = self[key] return false unless child.respond_to?(:has_key_path?) return child.has_key_path?(args[1..-1]) end |
#store_path(*args) ⇒ Object
Store a value at the specified nesting
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/more_core_extensions/core_ext/shared/nested.rb', line 66 def store_path(*args) raise ArgumentError, "must pass at least one key, and a value" if args.length < 2 value = args.pop child = self key = args.first if args.length > 1 || args.first.kind_of?(Array) keys = args.first.kind_of?(Array) ? args.first : args keys.each_with_index do |cur_key, i| raise ArgumentError, "must be a number" if child.kind_of?(Array) && !cur_key.kind_of?(Numeric) key = cur_key # keep track of this for value assignment later break if i + 1 == keys.size unless child[cur_key].respond_to?(:store_path) child[cur_key] = child.class.new end child = child[cur_key] end end child[key] = value end |