Module: Rjq::Path
- Defined in:
- lib/rjq/path.rb
Class Method Summary collapse
- .assert_path(path) ⇒ Object
- .delete(value, path) ⇒ Object
- .get(value, path) ⇒ Object
- .paths(value, leaves_only: false) ⇒ Object
- .read_index(value, index) ⇒ Object
- .set(value, path, new_value) ⇒ Object
Class Method Details
.assert_path(path) ⇒ Object
111 112 113 114 115 |
# File 'lib/rjq/path.rb', line 111 def assert_path(path) raise TypeError, 'Path must be specified as an array' unless path.is_a?(Array) path end |
.delete(value, path) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/rjq/path.rb', line 63 def delete(value, path) assert_path(path) return nil if path.empty? parent = get(value, path[0...-1]) key = path.last if slice_component?(key) replacement = parent.is_a?(String) ? '' : [] replace_slice(parent, key, replacement) return value end case parent when Array raise TypeError, (parent, key) unless key.is_a?(Numeric) return value if key.respond_to?(:finite?) && !key.finite? key = key.to_i return value if key.zero? && path.last.negative? key = parent.length + key if key.negative? parent.delete_at(key) unless key.negative? when Hash raise TypeError, (parent, key) unless key.is_a?(String) parent.delete(key) end value end |
.get(value, path) ⇒ Object
7 8 9 10 |
# File 'lib/rjq/path.rb', line 7 def get(value, path) assert_path(path) path.reduce(value) { |current, key| read_index(current, key) } end |
.paths(value, leaves_only: false) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/rjq/path.rb', line 92 def paths(value, leaves_only: false) out = [] stack = [[value, nil]] until stack.empty? current, path_node = stack.pop scalar = !(current.is_a?(Array) || current.is_a?(Hash)) out << materialize_path(path_node) if path_node.nil? || !leaves_only || scalar children = if current.is_a?(Array) current.each_with_index.map { |item, index| [item, [path_node, index]] } elsif current.is_a?(Hash) current.map { |key, item| [item, [path_node, key]] } else [] end stack.concat(children.reverse) end out end |
.read_index(value, index) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/rjq/path.rb', line 12 def read_index(value, index) return read_slice(value, index) if slice_component?(index) case value when NilClass raise TypeError, (value, index) unless index.is_a?(String) || index.is_a?(Numeric) nil when Array raise TypeError, (value, index) unless index.is_a?(Numeric) read_array(value, index) when Hash raise TypeError, (value, index) unless index.is_a?(String) value[index] when String raise TypeError, (value, index) else raise TypeError, (value, index) end end |
.set(value, path, new_value) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rjq/path.rb', line 35 def set(value, path, new_value) assert_path(path) return new_value if path.empty? if value.nil? read_index(nil, path.first) value = container_for(path.first) end parent = ensure_parent(value, path) key = path.last if slice_component?(key) replace_slice(parent, key, new_value) return value end key = normalize_array_key(parent, key) case parent when Array parent[key] = new_value when Hash raise TypeError, (parent, key) unless key.is_a?(String) parent[key] = new_value else raise TypeError, (parent, key) end value end |