Skip to content

Commit 6817fe8

Browse files
authored
Merge pull request #26 from B-CDD/change/rename-subject-to-source
Change/Rename result subject term/concept to result source
2 parents b0ae8f2 + 41ed4a9 commit 6817fe8

File tree

142 files changed

+328
-310
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+328
-310
lines changed

CHANGELOG.md

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
11
- [\[Unreleased\]](#unreleased)
2+
- [Changed](#changed)
23
- [\[0.11.0\] - 2024-01-02](#0110---2024-01-02)
34
- [Added](#added)
4-
- [Changed](#changed)
5+
- [Changed](#changed-1)
56
- [\[0.10.0\] - 2023-12-31](#0100---2023-12-31)
67
- [Added](#added-1)
78
- [\[0.9.1\] - 2023-12-12](#091---2023-12-12)
8-
- [Changed](#changed-1)
9+
- [Changed](#changed-2)
910
- [Fixed](#fixed)
1011
- [\[0.9.0\] - 2023-12-12](#090---2023-12-12)
1112
- [Added](#added-2)
12-
- [Changed](#changed-2)
13+
- [Changed](#changed-3)
1314
- [\[0.8.0\] - 2023-12-11](#080---2023-12-11)
1415
- [Added](#added-3)
15-
- [Changed](#changed-3)
16+
- [Changed](#changed-4)
1617
- [Removed](#removed)
1718
- [\[0.7.0\] - 2023-10-27](#070---2023-10-27)
1819
- [Added](#added-4)
19-
- [Changed](#changed-4)
20+
- [Changed](#changed-5)
2021
- [\[0.6.0\] - 2023-10-11](#060---2023-10-11)
2122
- [Added](#added-5)
22-
- [Changed](#changed-5)
23+
- [Changed](#changed-6)
2324
- [\[0.5.0\] - 2023-10-09](#050---2023-10-09)
2425
- [Added](#added-6)
2526
- [\[0.4.0\] - 2023-09-28](#040---2023-09-28)
2627
- [Added](#added-7)
27-
- [Changed](#changed-6)
28+
- [Changed](#changed-7)
2829
- [Removed](#removed-1)
2930
- [\[0.3.0\] - 2023-09-26](#030---2023-09-26)
3031
- [Added](#added-8)
@@ -36,6 +37,14 @@
3637

3738
## [Unreleased]
3839

40+
### Changed
41+
42+
- **(BREAKING)** Renames the subject concept/term to `source`. When a mixin is included/extended, it defines the `Success()` and `Failure()` methods. Since the results are generated in a context (instance or singleton where the mixin was used), they will have a defined source (instance or singleton itself).
43+
> Definition of source
44+
>
45+
> From dictionary:
46+
> * a place, person, or thing from which something comes or can be obtained.
47+
3948
## [0.11.0] - 2024-01-02
4049

4150
### Added
@@ -45,6 +54,14 @@
4554
### Changed
4655

4756
- **(BREAKING)** Rename halted concept to terminal. Failures are terminal by default, but you can make a success terminal by enabling the `:continue` addon.
57+
> Definition of terminal
58+
>
59+
> From dictionary:
60+
> * of, forming, or situated at the end or extremity of something.
61+
> * the end of a railroad or other transport route, or a station at such a point.
62+
>
63+
> From Wikipedia:
64+
> * A "terminus" or "terminal" is a station at the end of a railway line.
4865
4966
- **(BREAKING)** Rename `BCDD::Result::Context::Success#and_expose` halted keyword argument to `terminal`.
5067

README.md

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -649,9 +649,9 @@ Divide.call(2, 2)
649649

650650
This method generates a module that any object can include or extend. It adds two methods to the target object: `Success()` and `Failure()`.
651651

652-
The main difference between these methods and `BCDD::Result::Success()`/`BCDD::Result::Failure()` is that the former will utilize the target object (which has received the include/extend) as the result's subject.
652+
The main difference between these methods and `BCDD::Result::Success()`/`BCDD::Result::Failure()` is that the former will utilize the target object (which has received the include/extend) as the result's source.
653653

654-
Because the result has a subject, the `#and_then` method can call methods from it.
654+
Because the result has a source, the `#and_then` method can call methods from it.
655655

656656
##### Class example (Instance Methods)
657657

@@ -746,9 +746,9 @@ Divide.call(4, '2') #<BCDD::Result::Failure type=:invalid_arg value="arg2 must b
746746

747747
To use the `#and_then` method to call methods, they must use `Success()` and `Failure()` to produce the results.
748748

749-
If you try to use `BCDD::Result::Subject()`/`BCDD::Result::Failure()`, or results from another `BCDD::Result.mixin` instance with `#and_then`, it will raise an error because the subjects will be different.
749+
If you try to use `BCDD::Result::Success()`/`BCDD::Result::Failure()`, or results from another `BCDD::Result.mixin` instance with `#and_then`, it will raise an error because the sources are different.
750750

751-
**Note:** You can still use the block syntax, but all the results must be produced by the subject's `Success()` and `Failure()` methods.
751+
**Note:** You can still use the block syntax, but all the results must be produced by the source's `Success()` and `Failure()` methods.
752752

753753
```ruby
754754
module ValidateNonzero
@@ -794,13 +794,13 @@ Look at the error produced by the code above:
794794
```ruby
795795
Divide.call(2, 0)
796796

797-
# You cannot call #and_then and return a result that does not belong to the subject! (BCDD::Result::Error::InvalidResultSubject)
798-
# Expected subject: Divide
799-
# Given subject: ValidateNonzero
797+
# You cannot call #and_then and return a result that does not belong to the same source! (BCDD::Result::Error::InvalidResultSource)
798+
# Expected source: Divide
799+
# Given source: ValidateNonzero
800800
# Given result: #<BCDD::Result::Failure type=:division_by_zero value="arg2 must not be zero">
801801
```
802802

803-
In order to fix this, you must handle the result produced by `ValidateNonzero.call()` and return a result that belongs to the subject.
803+
In order to fix this, you must handle the result produced by `ValidateNonzero.call()` and return a result that belongs to the same source.
804804

805805
```ruby
806806
module ValidateNonzero
@@ -832,7 +832,8 @@ module Divide
832832
end
833833

834834
def validate_nonzero(numbers)
835-
# In this case we are handling the other subject result and returning our own
835+
# In this case we are handling the result from other source
836+
# and returning our own
836837
ValidateNonzero.call(numbers).handle do |on|
837838
on.success { |numbers| Success(:ok, numbers) }
838839

@@ -858,8 +859,8 @@ Divide.call(2, 0)
858859

859860
##### Dependency Injection
860861

861-
The `BCDD::Result#and_then` accepts a second argument that will be used to share a value with the subject's method.
862-
To receive this argument, the subject's method must have an arity of two, where the first argument will be the result value and the second will be the shared value.
862+
The `BCDD::Result#and_then` accepts a second argument that will be used to share a value with the source's method.
863+
To receive this argument, the source's method must have an arity of two, where the first argument will be the result value and the second will be the injected value.
863864

864865
```ruby
865866
require 'logger'
@@ -1863,23 +1864,23 @@ result.transitions
18631864
:parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
18641865
:current=>{:id=>1, :name=>"Division", :desc=>"divide two numbers"},
18651866
:result=>{:kind=>:success, :type=>:continued, :value=>[20, 2]},
1866-
:and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106099028>, :method_name=>:require_numbers},
1867+
:and_then=>{:type=>:method, :arg=>nil, :source=><Division:0x0000000106099028>, :method_name=>:require_numbers},
18671868
:time=>2024-01-02 03:35:11.248558 UTC
18681869
},
18691870
{
18701871
:root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
18711872
:parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
18721873
:current=>{:id=>1, :name=>"Division", :desc=>"divide two numbers"},
18731874
:result=>{:kind=>:success, :type=>:continued, :value=>[20, 2]},
1874-
:and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106099028>, :method_name=>:check_for_zeros},
1875+
:and_then=>{:type=>:method, :arg=>nil, :source=><Division:0x0000000106099028>, :method_name=>:check_for_zeros},
18751876
:time=>2024-01-02 03:35:11.248587 UTC
18761877
},
18771878
{
18781879
:root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
18791880
:parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
18801881
:current=>{:id=>1, :name=>"Division", :desc=>"divide two numbers"},
18811882
:result=>{:kind=>:success, :type=>:division_completed, :value=>10},
1882-
:and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106099028>, :method_name=>:divide},
1883+
:and_then=>{:type=>:method, :arg=>nil, :source=><Division:0x0000000106099028>, :method_name=>:divide},
18831884
:time=>2024-01-02 03:35:11.248607 UTC
18841885
},
18851886
{
@@ -1895,23 +1896,23 @@ result.transitions
18951896
:parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
18961897
:current=>{:id=>2, :name=>"Division", :desc=>"divide two numbers"},
18971898
:result=>{:kind=>:success, :type=>:continued, :value=>[10, 2]},
1898-
:and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106097ed0>, :method_name=>:require_numbers},
1899+
:and_then=>{:type=>:method, :arg=>nil, :source=><Division:0x0000000106097ed0>, :method_name=>:require_numbers},
18991900
:time=>2024-01-02 03:35:11.248661 UTC
19001901
},
19011902
{
19021903
:root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
19031904
:parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
19041905
:current=>{:id=>2, :name=>"Division", :desc=>"divide two numbers"},
19051906
:result=>{:kind=>:success, :type=>:continued, :value=>[10, 2]},
1906-
:and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106097ed0>, :method_name=>:check_for_zeros},
1907+
:and_then=>{:type=>:method, :arg=>nil, :source=><Division:0x0000000106097ed0>, :method_name=>:check_for_zeros},
19071908
:time=>2024-01-02 03:35:11.248672 UTC
19081909
},
19091910
{
19101911
:root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
19111912
:parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
19121913
:current=>{:id=>2, :name=>"Division", :desc=>"divide two numbers"},
19131914
:result=>{:kind=>:success, :type=>:division_completed, :value=>5},
1914-
:and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106097ed0>, :method_name=>:divide},
1915+
:and_then=>{:type=>:method, :arg=>nil, :source=><Division:0x0000000106097ed0>, :method_name=>:divide},
19151916
:time=>2024-01-02 03:35:11.248682 UTC
19161917
},
19171918
{

lib/bcdd/result.rb

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
class BCDD::Result
1717
attr_accessor :unknown, :transitions
1818

19-
attr_reader :subject, :data, :type_checker, :terminal
19+
attr_reader :source, :data, :type_checker, :terminal
2020

21-
protected :subject
21+
protected :source
2222

2323
private :unknown, :unknown=, :type_checker, :transitions=
2424

@@ -32,11 +32,11 @@ def self.configuration
3232
config.freeze
3333
end
3434

35-
def initialize(type:, value:, subject: nil, expectations: nil, terminal: nil)
35+
def initialize(type:, value:, source: nil, expectations: nil, terminal: nil)
3636
data = Data.new(kind, type, value)
3737

3838
@type_checker = Contract.evaluate(data, expectations)
39-
@subject = subject
39+
@source = source
4040
@terminal = terminal || kind == :failure
4141
@data = data
4242

@@ -93,7 +93,7 @@ def and_then(method_name = nil, context = nil, &block)
9393

9494
method_name && block and raise ::ArgumentError, 'method_name and block are mutually exclusive'
9595

96-
method_name ? call_and_then_subject_method(method_name, context) : call_and_then_block(block)
96+
method_name ? call_and_then_source_method(method_name, context) : call_and_then_block(block)
9797
end
9898

9999
def handle
@@ -139,27 +139,27 @@ def known(block)
139139
block.call(value, type)
140140
end
141141

142-
def call_and_then_subject_method(method_name, context_data)
143-
method = subject.method(method_name)
142+
def call_and_then_source_method(method_name, injected_value)
143+
method = source.method(method_name)
144144

145-
Transitions.tracking.record_and_then(method, context_data, subject) do
146-
result = call_and_then_subject_method!(method, context_data)
145+
Transitions.tracking.record_and_then(method, injected_value, source) do
146+
result = call_and_then_source_method!(method, injected_value)
147147

148148
ensure_result_object(result, origin: :method)
149149
end
150150
end
151151

152-
def call_and_then_subject_method!(method, context_data)
152+
def call_and_then_source_method!(method, injected_value)
153153
case method.arity
154-
when 0 then subject.send(method.name)
155-
when 1 then subject.send(method.name, value)
156-
when 2 then subject.send(method.name, value, context_data)
157-
else raise Error::InvalidSubjectMethodArity.build(subject: subject, method: method, max_arity: 2)
154+
when 0 then source.send(method.name)
155+
when 1 then source.send(method.name, value)
156+
when 2 then source.send(method.name, value, injected_value)
157+
else raise Error::InvalidSourceMethodArity.build(source: source, method: method, max_arity: 2)
158158
end
159159
end
160160

161161
def call_and_then_block(block)
162-
Transitions.tracking.record_and_then(:block, nil, subject) do
162+
Transitions.tracking.record_and_then(:block, nil, source) do
163163
result = call_and_then_block!(block)
164164

165165
ensure_result_object(result, origin: :block)
@@ -173,8 +173,8 @@ def call_and_then_block!(block)
173173
def ensure_result_object(result, origin:)
174174
raise Error::UnexpectedOutcome.build(outcome: result, origin: origin) unless result.is_a?(::BCDD::Result)
175175

176-
return result if result.subject.equal?(subject)
176+
return result if result.source.equal?(source)
177177

178-
raise Error::InvalidResultSubject.build(given_result: result, expected_subject: subject)
178+
raise Error::InvalidResultSource.build(given_result: result, expected_source: source)
179179
end
180180
end

lib/bcdd/result/context.rb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ def self.Failure(type, **value)
1515
Failure.new(type: type, value: value)
1616
end
1717

18-
def initialize(type:, value:, subject: nil, expectations: nil, terminal: nil)
18+
def initialize(type:, value:, source: nil, expectations: nil, terminal: nil)
1919
value.is_a?(::Hash) or raise ::ArgumentError, 'value must be a Hash'
2020

2121
@acc = {}
2222

2323
super
2424
end
2525

26-
def and_then(method_name = nil, **context_data, &block)
27-
super(method_name, context_data, &block)
26+
def and_then(method_name = nil, **injected_value, &block)
27+
super(method_name, injected_value, &block)
2828
end
2929

3030
protected
@@ -33,20 +33,20 @@ def and_then(method_name = nil, **context_data, &block)
3333

3434
private
3535

36-
SubjectMethodArity = ->(method) do
36+
SourceMethodArity = ->(method) do
3737
return 0 if method.arity.zero?
3838
return 1 if method.parameters.map(&:first).all?(/\Akey/)
3939

4040
-1
4141
end
4242

43-
def call_and_then_subject_method!(method, context_data)
44-
acc.merge!(value.merge(context_data))
43+
def call_and_then_source_method!(method, injected_value)
44+
acc.merge!(value.merge(injected_value))
4545

46-
case SubjectMethodArity[method]
47-
when 0 then subject.send(method.name)
48-
when 1 then subject.send(method.name, **acc)
49-
else raise Error::InvalidSubjectMethodArity.build(subject: subject, method: method, max_arity: 1)
46+
case SourceMethodArity[method]
47+
when 0 then source.send(method.name)
48+
when 1 then source.send(method.name, **acc)
49+
else raise Error::InvalidSourceMethodArity.build(source: source, method: method, max_arity: 1)
5050
end
5151
end
5252

@@ -59,9 +59,9 @@ def call_and_then_block!(block)
5959
def ensure_result_object(result, origin:)
6060
raise_unexpected_outcome_error(result, origin) unless result.is_a?(Context)
6161

62-
return result.tap { _1.acc.merge!(acc) } if result.subject.equal?(subject)
62+
return result.tap { _1.acc.merge!(acc) } if result.source.equal?(source)
6363

64-
raise Error::InvalidResultSubject.build(given_result: result, expected_subject: subject)
64+
raise Error::InvalidResultSource.build(given_result: result, expected_source: source)
6565
end
6666

6767
EXPECTED_OUTCOME = 'BCDD::Result::Context::Success or BCDD::Result::Context::Failure'
@@ -70,6 +70,6 @@ def raise_unexpected_outcome_error(result, origin)
7070
raise Error::UnexpectedOutcome.build(outcome: result, origin: origin, expected: EXPECTED_OUTCOME)
7171
end
7272

73-
private_constant :SubjectMethodArity, :EXPECTED_OUTCOME
73+
private_constant :SourceMethodArity, :EXPECTED_OUTCOME
7474
end
7575
end

lib/bcdd/result/context/expectations/mixin.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ module Expectations::Mixin
99
module Addons
1010
module Continue
1111
private def Continue(**value)
12-
Success.new(type: :continued, value: value, subject: self)
12+
Success.new(type: :continued, value: value, source: self)
1313
end
1414
end
1515

1616
module Given
1717
private def Given(*values)
1818
value = values.map(&:to_h).reduce({}) { |acc, val| acc.merge(val) }
1919

20-
Success.new(type: :given, value: value, subject: self)
20+
Success.new(type: :given, value: value, source: self)
2121
end
2222
end
2323

lib/bcdd/result/context/mixin.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def Failure(type, **value)
1414
end
1515

1616
private def _ResultAs(kind_class, type, value, terminal: nil)
17-
kind_class.new(type: type, value: value, subject: self, terminal: terminal)
17+
kind_class.new(type: type, value: value, source: self, terminal: terminal)
1818
end
1919
end
2020

lib/bcdd/result/context/success.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ def and_expose(type, keys, terminal: true)
1010

1111
exposed_value = acc.merge(value).slice(*keys)
1212

13-
self.class.new(type: type, value: exposed_value, subject: subject, terminal: terminal)
13+
self.class.new(type: type, value: exposed_value, source: source, terminal: terminal)
1414
end
1515
end

0 commit comments

Comments
 (0)