Class: Xf::Scope
- Inherits:
-
Object
- Object
- Xf::Scope
- Defined in:
- lib/xf/scope.rb
Overview
A play on Lenses in Ruby, though not quite as powerful they can be useful for getting and setting deep values on collections.
Instance Method Summary collapse
-
#get(&fn) ⇒ type
Gets a value from a Hash.
-
#get_value(hash, &fn) ⇒ Any
Direct value getter, though it may be wiser to use Hash#dig here instead if you’re concerned about speed.
-
#initialize(paths) ⇒ Xf::Scope
constructor
Creates a Scope.
-
#set(value = nil, &fn) ⇒ Proc[Hash] -
Sets a value in a Hash.
-
#set!(value = nil, &fn) ⇒ Object
Mutates a value in a Hash.
-
#set_value(hash, value = nil, &fn) ⇒ Hash
Sets a value at the bottom of a path without mutating the original.
-
#set_value!(hash, value = nil, &fn) ⇒ Object
Mutating form of ‘#set_value`.
Constructor Details
#initialize(paths) ⇒ Xf::Scope
Creates a Scope
13 14 15 |
# File 'lib/xf/scope.rb', line 13 def initialize(paths) @paths = paths end |
Instance Method Details
#get(&fn) ⇒ type
Gets a value from a Hash
20 21 22 |
# File 'lib/xf/scope.rb', line 20 def get(&fn) Proc.new { |hash| get_value(hash, &fn) } end |
#get_value(hash, &fn) ⇒ Any
Direct value getter, though it may be wiser to use Hash#dig here instead if you’re concerned about speed.
If the object does not respond to dig, Xf will attempt to use an array bracket accessor dive instead for compatability reasons.
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/xf/scope.rb', line 60 def get_value(hash, &fn) value = if hash.respond_to?(:dig) hash.dig(*@paths) else new_hash = hash @paths.each { |s| new_hash = new_hash[s] } new_hash end block_given? ? fn[value] : value end |
#set(value = nil, &fn) ⇒ Proc[Hash] -
Sets a value in a Hash
35 36 37 |
# File 'lib/xf/scope.rb', line 35 def set(value = nil, &fn) Proc.new { |hash| set_value(hash, value, &fn) } end |
#set!(value = nil, &fn) ⇒ Object
This method does the same thing as ‘#set`, except that it mutates the target value instead of creating a clone first.
Mutates a value in a Hash
47 48 49 |
# File 'lib/xf/scope.rb', line 47 def set!(value = nil, &fn) Proc.new { |hash| set_value!(hash, value, &fn) } end |
#set_value(hash, value = nil, &fn) ⇒ Hash
Sets a value at the bottom of a path without mutating the original.
86 87 88 |
# File 'lib/xf/scope.rb', line 86 def set_value(hash, value = nil, &fn) set_value!(deep_clone(hash), value, &fn) end |
#set_value!(hash, value = nil, &fn) ⇒ Object
Mutating form of ‘#set_value`
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/xf/scope.rb', line 93 def set_value!(hash, value = nil, &fn) lead_in = @paths[0..-2] target_key = @paths[-1] new_hash = hash lead_in.each { |s| new_hash = new_hash[s] } new_value = block_given? ? yield(new_hash[target_key]) : value new_hash[target_key] = new_value hash end |