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

Instance Method Details

#deep_cloneObject

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

Raises:

  • (ArgumentError)


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

Raises:

  • (ArgumentError)


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

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


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

Raises:

  • (ArgumentError)


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