deterministic 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Guardfile +5 -2
- data/README.md +60 -0
- data/lib/deterministic/either/chain.rb +13 -0
- data/lib/deterministic/either.rb +1 -5
- data/lib/deterministic/version.rb +1 -1
- data/lib/deterministic.rb +1 -0
- data/spec/lib/deterministic/either/chain_spec.rb +60 -0
- data/spec/lib/deterministic/either/either_shared.rb +0 -4
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02fd1f0c22527cf4af1af78fdb8e868d4947fb3b
|
4
|
+
data.tar.gz: 0efb14c1c44f3d487e551765a1fb671b8e9b55c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb9ab93ae058be25b8f724d4c246138ce6f576cf59f6bcf8e6927a97fbbd67f42fff1a527f7bcf791d858fd03d1108a8f756457a3bb0b345c82b5aa83c5ef7d2
|
7
|
+
data.tar.gz: a40bc7baf45c6785b0204faca45f9e5c3a4eb4f33e0baae1c647da5591bc464051bb58f8b109c09518c6aad80ae1f112d5a7659ea0df1d721db3d3ae38d55e86
|
data/Guardfile
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
guard :bundler do
|
2
|
+
watch('Gemfile')
|
3
|
+
end
|
4
|
+
|
1
5
|
guard :bundler do
|
2
6
|
watch('Gemfile')
|
3
7
|
watch(/^.+\.gemspec/)
|
4
8
|
end
|
5
9
|
|
6
|
-
guard :rspec do
|
10
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
7
11
|
watch(%r{^spec/.+_spec\.rb$})
|
8
12
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
9
13
|
watch('spec/spec_helper.rb') { "spec" }
|
@@ -12,4 +16,3 @@ guard :rspec do
|
|
12
16
|
watch(%r{^spec/acceptance/(.+)\.feature$})
|
13
17
|
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
14
18
|
end
|
15
|
-
|
data/README.md
CHANGED
@@ -47,10 +47,70 @@ Failure(1).or_else { |v| Success(v)} # => Success(1)
|
|
47
47
|
|
48
48
|
The value or block result must always be a `Success` or `Failure`
|
49
49
|
|
50
|
+
### Either.chain
|
51
|
+
You can easily chain the execution of several operations. Here we got some nice function composition.
|
52
|
+
The method must be a unary function, i.e. it always takes one parameter - the context, which is passed from call to call.
|
50
53
|
|
54
|
+
```ruby
|
55
|
+
class Foo
|
56
|
+
include Deterministic
|
57
|
+
alias :m :method
|
58
|
+
|
59
|
+
def call
|
60
|
+
setup >> m(:validate) >> m(:send)
|
61
|
+
end
|
62
|
+
|
63
|
+
def setup
|
64
|
+
Success(1)
|
65
|
+
end
|
66
|
+
|
67
|
+
def validate(ctx)
|
68
|
+
# do stuff
|
69
|
+
Success(ctx + 1)
|
70
|
+
end
|
71
|
+
|
72
|
+
def send(ctx)
|
73
|
+
# do stuff
|
74
|
+
Success(ctx + 1)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
Foo.new.call # Success(3)
|
79
|
+
```
|
80
|
+
|
81
|
+
Chaining works with blocks (`#chain` is an alias for `#>>`)
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
Success(1).chain {|ctx| Success(ctx + 1)}
|
85
|
+
```
|
86
|
+
|
87
|
+
it also works with lambdas
|
88
|
+
```ruby
|
89
|
+
Success(1) >> ->(ctx) { Success(ctx + 1) } >> ->(ctx) { Success(ctx + 1) }
|
90
|
+
```
|
91
|
+
|
92
|
+
and it will break the chain of execution, when it encounters a `Failure` on its way
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
def works(ctx)
|
96
|
+
Success(1)
|
97
|
+
end
|
98
|
+
|
99
|
+
def breaks(ctx)
|
100
|
+
Failure(2)
|
101
|
+
end
|
102
|
+
|
103
|
+
def never_executed(ctx)
|
104
|
+
Success(99)
|
105
|
+
end
|
106
|
+
|
107
|
+
Success(0) >> method(:works) >> method(:breaks) >> method(:never_executed) # Failure(2)
|
108
|
+
```
|
51
109
|
|
52
110
|
### Either.attempt_all
|
53
111
|
The basic idea is to execute a chain of units of work and make sure all return either `Success` or `Failure`.
|
112
|
+
This remains for compatibility reasons, personally I would use the `>>` chaining.
|
113
|
+
|
54
114
|
|
55
115
|
```ruby
|
56
116
|
Either.attempt_all do
|
data/lib/deterministic/either.rb
CHANGED
@@ -3,6 +3,7 @@ module Deterministic
|
|
3
3
|
class Either
|
4
4
|
include Monad
|
5
5
|
include Deterministic::PatternMatching
|
6
|
+
include Chain
|
6
7
|
|
7
8
|
def bind(proc=nil, &block)
|
8
9
|
(proc || block).call(value, self.class).tap do |result|
|
@@ -28,11 +29,6 @@ module Deterministic
|
|
28
29
|
protected :new
|
29
30
|
end
|
30
31
|
|
31
|
-
def to_json(*args)
|
32
|
-
name = self.class.name.split('::')[-1]
|
33
|
-
"{\"#{name}\":#{value.to_json(*args)}}"
|
34
|
-
end
|
35
|
-
|
36
32
|
def to_s
|
37
33
|
value.to_s
|
38
34
|
end
|
data/lib/deterministic.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include Deterministic
|
4
|
+
|
5
|
+
describe Deterministic::Either do
|
6
|
+
context ">>" do
|
7
|
+
it "Failure stops execution" do
|
8
|
+
class ChainUnderTest
|
9
|
+
alias :m :method
|
10
|
+
|
11
|
+
def call
|
12
|
+
init >> m(:validate) >> m(:send) >> m(:parse)
|
13
|
+
end
|
14
|
+
|
15
|
+
def init
|
16
|
+
Success({step: 1})
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate(i)
|
20
|
+
i[:step] = i[:step] + 1
|
21
|
+
Success(i)
|
22
|
+
end
|
23
|
+
|
24
|
+
def send(i)
|
25
|
+
i[:step] = i[:step] + 1
|
26
|
+
Failure("Error @ #{i.fetch(:step)}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse(i)
|
30
|
+
i[:step] = i[:step] + 1
|
31
|
+
Success(i)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
test = ChainUnderTest.new
|
36
|
+
|
37
|
+
expect(test.call).to eq Failure("Error @ 3")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "expects an Either" do
|
41
|
+
def returns_non_either(i)
|
42
|
+
2
|
43
|
+
end
|
44
|
+
|
45
|
+
expect { Success(1) >> method(:returns_non_either) }.to raise_error(Deterministic::Monad::NotMonadError)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "works with a block" do
|
49
|
+
expect(
|
50
|
+
Success(1).chain { |i| Success(i + 1) }
|
51
|
+
).to eq Success(2)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "works with a lambda" do
|
55
|
+
expect(
|
56
|
+
Success(1) >> ->(i) { Success(i + 1) }
|
57
|
+
).to eq Success(2)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -11,10 +11,6 @@ shared_examples 'Either' do
|
|
11
11
|
expect(either.new(1).bind { |v| either.new(v + 1)}).to eq either.new(2)
|
12
12
|
end
|
13
13
|
|
14
|
-
it "#to_json" do
|
15
|
-
expect(either.new({a: 1}).to_json).to eq "{\"#{either_name}\":{\"a\":1}}"
|
16
|
-
end
|
17
|
-
|
18
14
|
it "#to_s" do
|
19
15
|
expect(either.new(1).to_s).to eq "1"
|
20
16
|
expect(either.new({a: 1}).to_s).to eq "{:a=>1}"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deterministic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Zolnierek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -129,6 +129,7 @@ files:
|
|
129
129
|
- lib/deterministic/core_ext/object/either.rb
|
130
130
|
- lib/deterministic/either.rb
|
131
131
|
- lib/deterministic/either/attempt_all.rb
|
132
|
+
- lib/deterministic/either/chain.rb
|
132
133
|
- lib/deterministic/either/failure.rb
|
133
134
|
- lib/deterministic/either/match.rb
|
134
135
|
- lib/deterministic/either/success.rb
|
@@ -141,6 +142,7 @@ files:
|
|
141
142
|
- spec/lib/deterministic/attempt_all_spec.rb
|
142
143
|
- spec/lib/deterministic/core_ext/either_spec.rb
|
143
144
|
- spec/lib/deterministic/core_ext/object/either_spec.rb
|
145
|
+
- spec/lib/deterministic/either/chain_spec.rb
|
144
146
|
- spec/lib/deterministic/either/either_shared.rb
|
145
147
|
- spec/lib/deterministic/either/failure_spec.rb
|
146
148
|
- spec/lib/deterministic/either/match_spec.rb
|
@@ -181,6 +183,7 @@ test_files:
|
|
181
183
|
- spec/lib/deterministic/attempt_all_spec.rb
|
182
184
|
- spec/lib/deterministic/core_ext/either_spec.rb
|
183
185
|
- spec/lib/deterministic/core_ext/object/either_spec.rb
|
186
|
+
- spec/lib/deterministic/either/chain_spec.rb
|
184
187
|
- spec/lib/deterministic/either/either_shared.rb
|
185
188
|
- spec/lib/deterministic/either/failure_spec.rb
|
186
189
|
- spec/lib/deterministic/either/match_spec.rb
|