xf 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9df7279d149753a1c1a73ad78abf38d217ad745adcf914a3c561fb776b1f116a
4
- data.tar.gz: 709dad6362cf6792ae3d7051f563940161a6dfd666074f156760712f53c8eec2
3
+ metadata.gz: 834016d61fb0ca6d052c441bd9ca2a864e859ae3573fd94a85a6b35d90741169
4
+ data.tar.gz: 364f4a15f6cfb7495a201a4093105f0dc3796fbe0f5f3faa403b541ce56eade0
5
5
  SHA512:
6
- metadata.gz: 74261ad1e8b45bae2bfa7a65e349619270f0e57920c3517c02387dfa849dca81a4f5249aef1baf0b365335b03d3c93cceb227fdc59cf8a5afecea6a30ef202bd
7
- data.tar.gz: d8b33f75ecf8b681593058e9d19f6f453b35bb0723169f3fabf2848b7b953276de459b0eaeeee50d0dad19c94b8bbfbcc3aafb3cb1779ed062e2fc00e0b3179c
6
+ metadata.gz: 199dd67f1f1bfc4f607c11e9f5c4c1cf25ec69844d265320ea610932055e3d859c2a52d294262581de26e3613657e8de5034fede1dd57bf053423513268061d4
7
+ data.tar.gz: b929b55e0789431a0362238c6405dc06372fabe29a2e53ae5f61f649e76dc77197f0c0a73282e07b7e519e8e3185642980792f9e903f66e2e9fc22726ec8d753
@@ -12,7 +12,7 @@ module Xf
12
12
  end
13
13
 
14
14
  def self.version
15
- "0.0.1"
15
+ "0.0.2"
16
16
  end
17
17
 
18
18
  def self.version_label
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'xf/scope'
4
+
3
5
  module Xf
4
6
  module PublicApi
5
7
  # Composes a list of functions, or items that respond to `to_proc`, into
@@ -17,5 +19,9 @@ module Xf
17
19
  end
18
20
 
19
21
  alias_method :c, :compose
22
+
23
+ def scope(*path)
24
+ Scope.new(path)
25
+ end
20
26
  end
21
27
  end
@@ -0,0 +1,81 @@
1
+ module Xf
2
+ # A play on Lenses in Ruby, though not quite as powerful they can be
3
+ # useful for getting and setting deep values on collections.
4
+ #
5
+ # @author baweaver
6
+ # @since 0.0.2
7
+ #
8
+ class Scope
9
+ # Creates a Scope
10
+ # @param paths [Array[Any]] Paths to follow to reach the desired value
11
+ #
12
+ # @return [Xf::Scope]
13
+ def initialize(paths)
14
+ @paths = paths
15
+ end
16
+
17
+ # Gets a value from a Hash
18
+ #
19
+ # @return [type] [description]
20
+ def get
21
+ method(:get_value)
22
+ end
23
+
24
+ # Sets a value in a Hash
25
+ #
26
+ # @param value = nil [Any]
27
+ # Value to set at the target
28
+ #
29
+ # @param &fn [Proc]
30
+ # Block to yield target value to. Returned value will be set as the new
31
+ # value at the target.
32
+ #
33
+ # @return [Proc[Hash] -> Hash]
34
+ # New Hash with transformation applied
35
+ def set(value = nil, &fn)
36
+ Proc.new { |hash| set_value(hash, value, &fn) }
37
+ end
38
+
39
+ # Mutates a value in a Hash
40
+ #
41
+ # @see #set
42
+ #
43
+ # @note
44
+ # This method does the same thing as `#set`, except that it mutates the
45
+ # target value instead of creating a clone first.
46
+ #
47
+ def set!(value = nil, &fn)
48
+ Proc.new { |hash| set_value!(hash, value, &fn) }
49
+ end
50
+
51
+ # Private API - Methods below here are subject to change, please don't use
52
+ # them directly.
53
+
54
+ private def get_value(hash)
55
+ hash.dig(*@paths)
56
+ end
57
+
58
+ private def set_value(hash, value = nil, &fn)
59
+ set_value!(deep_clone(hash), value, &fn)
60
+ end
61
+
62
+ private def set_value!(hash, value = nil, &fn)
63
+ lead_in = @paths[0..-2]
64
+ target_key = @paths[-1]
65
+
66
+ dive = lead_in.reduce(hash) { |h, s| h[s] }
67
+
68
+ new_value = block_given? ?
69
+ yield(dive[target_key]) :
70
+ value
71
+
72
+ dive[target_key] = new_value
73
+
74
+ hash
75
+ end
76
+
77
+ private def deep_clone(hash)
78
+ Marshal.load(Marshal.dump(hash))
79
+ end
80
+ end
81
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Weaver
@@ -178,6 +178,7 @@ files:
178
178
  - lib/xf.rb
179
179
  - lib/xf/identity.rb
180
180
  - lib/xf/public_api.rb
181
+ - lib/xf/scope.rb
181
182
  homepage: https://www.github.com/baweaver/xf
182
183
  licenses:
183
184
  - MIT