Module: Rucursive::CoreExt::Object
- Defined in:
- lib/rucursive/core_ext.rb
Instance Method Summary collapse
- #compound? ⇒ Boolean
-
#recurse(&block) ⇒ Object
Recursively traverse a compound data structure and call a supplied block on each value or key/value pair, allowing it to modify the returned data structure as it goes.
-
#recurse_keys(&block) ⇒ Object
Just like Object#recurse when called on a Hash, but only passes the keys to the supplied block, rather than the keys and values.
-
#recurse_values(&block) ⇒ Object
Just like Object#recurse when called on a Hash, but only passes the values to the supplied block, rather than the keys and values.
Instance Method Details
#compound? ⇒ Boolean
4 5 6 |
# File 'lib/rucursive/core_ext.rb', line 4 def compound? is_a?(Array) || is_a?(Hash) end |
#recurse(&block) ⇒ Object
Recursively traverse a compound data structure and call a supplied block on each value or key/value pair, allowing it to modify the returned data structure as it goes. It does NOT modify the existing data structure.
Required arguments: A block that is called on each element of the data
structure
Return value: A new data structure including any modifications made by
the supplied block.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 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 62 63 64 65 |
# File 'lib/rucursive/core_ext.rb', line 19 def recurse(&block) if is_a?(Array) map do |o| if o.compound? o.recurse(&block) else block.call(o.dup) if block.arity == 1 block.call(nil, o.dup) if block.arity == 2 block.call(nil, o.dup, :array) if block.arity == 3 end end elsif is_a?(Hash) new_hash = {} each_pair do |k,v| if v.compound? result = block.call(k, v.dup.freeze) if block.arity == 2 result = block.call(k, v.dup.freeze, :hash) if block.arity == 3 if result.is_a?(Hash) new_key = result.keys.first elsif result.is_a?(Array) new_key = result.first else new_key = result end new_hash[new_key] = v.recurse(&block) else begin v_param = v.dup rescue v_param = v end result = block.call(k, v_param) if block.arity == 2 result = block.call(k, v_param, :hash) if block.arity == 3 if result.is_a?(Hash) new_hash.merge! result elsif result.is_a?(Array) new_hash[result.first] = result.second else new_hash[result] = v end end end new_hash else self end end |
#recurse_keys(&block) ⇒ Object
Just like Object#recurse when called on a Hash, but only passes the keys to the supplied block, rather than the keys and values. Recurses through Arrays looking for Hashes, since Arrays don’t really have keys.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/rucursive/core_ext.rb', line 100 def recurse_keys(&block) if is_a?(Array) map do |o| if o.compound? o.recurse_keys(&block) else o end end elsif is_a?(Hash) new_hash = {} keys.each do |k| new_key = block.call k new_hash[new_key] = self[k] end new_hash.each_pair do |k,v| if v.is_a?(Hash) new_hash[k] = v.recurse_keys(&block) elsif v.is_a?(Array) new_ary = v.map do |o| o.is_a?(Hash) ? o.recurse_keys(&block) : o end new_hash[k] = new_ary end end new_hash else self end end |
#recurse_values(&block) ⇒ Object
Just like Object#recurse when called on a Hash, but only passes the values to the supplied block, rather than the keys and values. Behaves the same as Object#recurse on Arrays.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/rucursive/core_ext.rb', line 71 def recurse_values(&block) if is_a?(Array) map do |o| if o.compound? o.recurse_values(&block) else block.call o end end elsif is_a?(Hash) new_hash = {} each_pair do |k,v| if v.compound? new_hash[k] = v.recurse_values(&block) else new_hash[k] = block.call v end end new_hash else self end end |