chainit 1.1.0 → 1.2.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/README.md +59 -28
- data/lib/chain_it.rb +13 -0
- data/lib/chain_it/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fd7e2e3e12a8707ca3992b5d229395ce0a50e62
|
4
|
+
data.tar.gz: beaeefe42f9984cc4be7d564c34ef2553b01c8ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 143eb82b10d0c3b877fac51cc6bf11db176c253c37d00e2effd7cdb2d95b35d3319bc7a8a8da081abf4cc8840e7c9711a486282f9ee7bfe157c4546fba0e5286
|
7
|
+
data.tar.gz: 744156b8e3b84a97d260bfe9225d329c76e5758d23745743363d2be12f255938e46ed975423bd1b1f69d3e0e30709f4274b0533d1e458a29b21a97d7c6019c37
|
data/README.md
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
# ChainIt
|
2
|
-
|
2
|
+
### Gain full control over what is going in your code!
|
3
|
+
[](https://circleci.com/gh/tier-tools/chainit/tree/master)
|
3
4
|
|
4
|
-
##
|
5
|
-
|
6
|
-
(Read more on this <a href="https://fsharpforfunandprofit.com/rop">here</a>).
|
5
|
+
## What exactly is `ChainIt`?
|
6
|
+
It's the Ruby implementation of a railway-oriented programming concept. <a href="https://fsharpforfunandprofit.com/rop">read more</a>
|
7
7
|
|
8
|
-
|
8
|
+
The gem makes it super easy to control complex operations flow - the next step will happen only if the previous one was successful.
|
9
9
|
|
10
|
-
|
11
|
-
Everything comes down to chaining subsequent `#chain` method calls to a `ChainIt` object instance.
|
10
|
+
Ideally suited for handling task sequences that should be interrupted as soon as any subsequent task fails.
|
12
11
|
|
13
|
-
|
12
|
+
## How should I use `ChainIt`?
|
13
|
+
As not hard to guess, alll is about chaining subsequent `#chain` method calls to a `ChainIt` instance.
|
14
|
+
|
15
|
+
### Prerequisites
|
16
|
+
The gem supports design-by-contract programming concept assuming `ChainIt` will be used together with both `#value` and `#failure?` aware object that have to be returned by every `#chain`related block. It is used to consider the operation successful or failed.
|
17
|
+
|
18
|
+
We reccomend using `Struct`:
|
14
19
|
|
15
20
|
```ruby
|
16
21
|
Result = Struct.new(:success, :value) do
|
@@ -20,42 +25,68 @@ Result = Struct.new(:success, :value) do
|
|
20
25
|
end
|
21
26
|
|
22
27
|
```
|
23
|
-
###
|
28
|
+
### Interface explanation
|
29
|
+
`#initialize` - Initiates the operation. Auto exception handling mode is configurable here. (see examples section)</br>
|
30
|
+
`#chain` - Performs the code in its related block and memorizes the internal result value. This is done only when the state of the operation allows it.</br>
|
31
|
+
`#skip_next` - Skips the next `#chain` call when it's block evaluates to `true`.</br>
|
32
|
+
`#result` - The result of the operation representing succes of failure. </br>
|
33
|
+
|
34
|
+
### `ChainIt` modes
|
35
|
+
`auto_exception_handling` - default `false` - Decide if any `StandardError` exception should be rescued from any `#chain` call. If so the rescued exception will be memorized as operation result object.
|
24
36
|
|
37
|
+
### Examples </br>
|
38
|
+
#### Success path
|
25
39
|
```ruby
|
26
|
-
# Basic flow explanation
|
27
40
|
success = ->(value) { Result.new(true, value) }
|
28
41
|
|
29
|
-
ChainIt.new.
|
30
|
-
chain { success.call 2 }. #=> The subsequent chain will be triggered
|
31
|
-
chain { |num| success.call(num * 2) }. #=> We can pass the previous block evaluation as the block argument
|
32
|
-
chain { |num| success.call(num * 2) }.
|
33
|
-
result.
|
34
|
-
value #=> 8
|
35
|
-
|
36
|
-
# Working with #skip_next
|
37
42
|
ChainIt.new.
|
38
43
|
chain { success.call 2 }.
|
39
|
-
|
40
|
-
|
41
|
-
chain { |num| success.call(num * 2) }. #=> The block argument is the last executed #chain value
|
42
|
-
result.
|
44
|
+
chain { |num| success.call(num * 2) }. # The operation result is passed as block argument if used.
|
45
|
+
result. #=> <struct Result success=true, value=4>
|
43
46
|
value #=> 4
|
44
47
|
|
45
|
-
|
48
|
+
```
|
49
|
+
|
50
|
+
#### Failure path
|
51
|
+
```ruby
|
46
52
|
failure = ->(value) { Result.new(false, value) }
|
47
53
|
|
48
54
|
ChainIt.new.
|
49
55
|
chain { success.call 2 }.
|
50
|
-
chain { failure.call 0 }.
|
56
|
+
chain { failure.call 0 }. # All later steps calls will be skipped.
|
51
57
|
chain { success.call 4 }.
|
52
|
-
result.
|
58
|
+
result. #=> <struct Result success=false, value=0>
|
53
59
|
value #=> 0
|
54
60
|
```
|
55
|
-
|
61
|
+
#### Working with `#skip_next`
|
62
|
+
```ruby
|
63
|
+
ChainIt.new.
|
64
|
+
chain { success.call 2 }.
|
65
|
+
skip_next { |num| num == 2 }. # The next chain will be skipped as the block evaluates to true.
|
66
|
+
chain { success.call 8 }.
|
67
|
+
result. #=> <struct Result success=true, value=2>
|
68
|
+
value #=> 2
|
69
|
+
```
|
70
|
+
|
71
|
+
#### With `auto_exception_handling` mode disabled
|
72
|
+
```ruby
|
73
|
+
ChainIt.new.
|
74
|
+
chain { raise StandardError.new }. #=> StandardError: StandardError
|
75
|
+
result.
|
76
|
+
value
|
77
|
+
```
|
78
|
+
|
79
|
+
#### With `auto_exception_handling` mode enabled
|
80
|
+
```ruby
|
81
|
+
ChainIt.new(auto_exception_handling: true).
|
82
|
+
chain { raise StandardError.new }.
|
83
|
+
result. #=> <StandardError: StandardError>
|
84
|
+
value #=> <StandardError: StandardError>
|
85
|
+
```
|
56
86
|
|
57
|
-
|
87
|
+
## Develop `ChainIt`
|
88
|
+
All the contributions are really welcome on GitHub at https://github.com/tier-tools/chainit according to the open-source spirit.
|
58
89
|
|
59
|
-
## License
|
90
|
+
## `ChainIt` License
|
60
91
|
|
61
92
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/chain_it.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
class ChainIt
|
2
|
+
DEFAULT_SETTINGS = { auto_exception_handling: false }.freeze
|
2
3
|
INVALID_RESULT_MSG = "ChainIt#chain block must return both #value and #failure? aware object.\n Check documentation: https://github.com/spark-solutions/chain_it#usage"
|
3
4
|
|
5
|
+
def initialize(settings = {})
|
6
|
+
@settings = DEFAULT_SETTINGS.merge(settings)
|
7
|
+
end
|
8
|
+
|
4
9
|
def chain
|
5
10
|
if @skip_next
|
6
11
|
@skip_next = false
|
@@ -13,6 +18,14 @@ class ChainIt
|
|
13
18
|
@result = yield result_value
|
14
19
|
@skip = true if result_failure?
|
15
20
|
self
|
21
|
+
rescue StandardError => e
|
22
|
+
raise e unless @settings[:auto_exception_handling]
|
23
|
+
|
24
|
+
e.define_singleton_method(:value) { e }
|
25
|
+
@result = e
|
26
|
+
|
27
|
+
@skip = true
|
28
|
+
self
|
16
29
|
end
|
17
30
|
|
18
31
|
def skip_next
|
data/lib/chain_it/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chainit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- btolarz
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-08-
|
12
|
+
date: 2018-08-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
94
|
version: '0'
|
95
95
|
requirements: []
|
96
96
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.
|
97
|
+
rubygems_version: 2.5.2.1
|
98
98
|
signing_key:
|
99
99
|
specification_version: 4
|
100
100
|
summary: A tool for executing successive tasks in a railway-oriented manner
|