bcdd-result 0.7.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
2
  <h1 align="center" id="-bcddresult">🔀 BCDD::Result</h1>
3
- <p align="center"><i>Empower Ruby apps with a pragmatic use of Railway Oriented Programming.</i></p>
3
+ <p align="center"><i>Empower Ruby apps with pragmatic use of Result pattern (monad), Railway Oriented Programming, and B/CDD.</i></p>
4
4
  <p align="center">
5
5
  <img src="https://img.shields.io/badge/ruby->%3D%202.7.0-ruby.svg?colorA=99004d&colorB=cc0066" alt="Ruby">
6
6
  <a href="https://rubygems.org/gems/bcdd-result"><img src="https://badge.fury.io/rb/bcdd-result.svg" alt="bcdd-result gem version" height="18"></a>
@@ -23,7 +23,7 @@ Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofi
23
23
  - [`BCDD::Result` *versus* `Result`](#bcddresult-versus-result)
24
24
  - [Reference](#reference)
25
25
  - [Result Attributes](#result-attributes)
26
- - [Receiving types in `result.success?` or `result.failure?`](#receiving-types-in-resultsuccess-or-resultfailure)
26
+ - [Checking types with `result.success?` or `result.failure?`](#checking-types-with-resultsuccess-or-resultfailure)
27
27
  - [Result Hooks](#result-hooks)
28
28
  - [`result.on`](#resulton)
29
29
  - [`result.on_type`](#resulton_type)
@@ -63,12 +63,19 @@ Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofi
63
63
  - [`BCDD::Result::Expectations.mixin` add-ons](#bcddresultexpectationsmixin-add-ons)
64
64
  - [`BCDD::Result::Context`](#bcddresultcontext)
65
65
  - [Defining successes and failures](#defining-successes-and-failures)
66
+ - [Constant aliases](#constant-aliases)
66
67
  - [`BCDD::Result::Context.mixin`](#bcddresultcontextmixin)
67
68
  - [Class example (Instance Methods)](#class-example-instance-methods-1)
68
69
  - [`and_expose`](#and_expose)
69
70
  - [Module example (Singleton Methods)](#module-example-singleton-methods-1)
70
71
  - [`BCDD::Result::Context::Expectations`](#bcddresultcontextexpectations)
71
72
  - [Mixin add-ons](#mixin-add-ons)
73
+ - [`BCDD::Result.configuration`](#bcddresultconfiguration)
74
+ - [`config.addon.enable!(:continue)`](#configaddonenablecontinue)
75
+ - [`config.constant_alias.enable!('Result', 'BCDD::Context')`](#configconstant_aliasenableresult-bcddcontext)
76
+ - [`config.pattern_matching.disable!(:nil_as_valid_value_checking)`](#configpattern_matchingdisablenil_as_valid_value_checking)
77
+ - [`config.feature.disable!(:expectations)`](#configfeaturedisableexpectations)
78
+ - [`BCDD::Result.config`](#bcddresultconfig)
72
79
  - [About](#about)
73
80
  - [Development](#development)
74
81
  - [Contributing](#contributing)
@@ -84,7 +91,7 @@ Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofi
84
91
  Add this line to your application's Gemfile:
85
92
 
86
93
  ```ruby
87
- gem 'bcdd-result', require: 'bcdd/result'
94
+ gem 'bcdd-result'
88
95
  ```
89
96
 
90
97
  And then execute:
@@ -95,6 +102,10 @@ If bundler is not being used to manage dependencies, install the gem by executin
95
102
 
96
103
  $ gem install bcdd-result
97
104
 
105
+ And require it in your code:
106
+
107
+ require 'bcdd/result'
108
+
98
109
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
99
110
 
100
111
  ## Usage
@@ -119,17 +130,27 @@ BCDD::Result::Failure(:err) #
119
130
 
120
131
  #### `BCDD::Result` *versus* `Result`
121
132
 
122
- The `BCDD::Result` is the main module of this gem. It contains all the features, constants, and methods you will use to create and manipulate results.
133
+ This gem provides a way to create constant aliases for `BCDD::Result` and other classes/modules.
123
134
 
124
- The `Result` is an alias of `BCDD::Result`. It was created to facilitate the use of this gem in the code. So, instead of requiring `BCDD::Result` everywhere, you can require `Result` and use it as an alias.
135
+ To enable it, you must call the `BCDD::Result.configuration` method and pass a block to it. You can turn the aliases you want on/off in this block.
125
136
 
126
137
  ```ruby
127
- require 'result'
138
+ BCDD::Result.configuration do |config|
139
+ config.constant_alias.enable!('Result')
140
+ end
141
+ ```
142
+
143
+ So, instead of using `BCDD::Result` everywhere, you can use `Result` as an alias/shortcut.
128
144
 
145
+ ```ruby
129
146
  Result::Success(:ok) # <BCDD::Result::Success type=:ok value=nil>
147
+
148
+ Result::Failure(:err) # <BCDD::Result::Failure type=:err value=nil>
130
149
  ```
131
150
 
132
- All the examples in this README that use `BCDD::Result` can also be used with `Result`.
151
+ If you have enabled constant aliasing, all examples in this README that use `BCDD::Result` can be implemented using `Result`.
152
+
153
+ There are other aliases and configurations available. Check the [BCDD::Result.configuration]() section for more information.
133
154
 
134
155
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
135
156
 
@@ -169,12 +190,12 @@ result.value # nil
169
190
  ################
170
191
  # With a value #
171
192
  ################
172
- result = BCDD::Result::Failure(:err, my: 'value')
193
+ result = BCDD::Result::Failure(:err, 'my_value')
173
194
 
174
195
  result.success? # false
175
196
  result.failure? # true
176
197
  result.type # :err
177
- result.value # {:my => "value"}
198
+ result.value # "my_value"
178
199
 
179
200
  ###################
180
201
  # Without a value #
@@ -187,9 +208,11 @@ result.type # :no
187
208
  result.value # nil
188
209
  ```
189
210
 
211
+ In both cases, the `type` must be a symbol, and the `value` can be any kind of object.
212
+
190
213
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
191
214
 
192
- #### Receiving types in `result.success?` or `result.failure?`
215
+ #### Checking types with `result.success?` or `result.failure?`
193
216
 
194
217
  `BCDD::Result#success?` and `BCDD::Result#failure?` are methods that allow you to check if the result is a success or a failure.
195
218
 
@@ -198,9 +221,11 @@ You can also check the result type by passing an argument to it. For example, `r
198
221
  ```ruby
199
222
  result = BCDD::Result::Success(:ok)
200
223
 
201
- result.success? # true
202
- result.success?(:ok) # true
203
- result.success?(:okay) # false
224
+ result.success?(:ok)
225
+
226
+ # This is the same as:
227
+
228
+ result.success? && result.type == :ok
204
229
  ```
205
230
 
206
231
  The same is valid for `BCDD::Result#failure?`.
@@ -208,9 +233,11 @@ The same is valid for `BCDD::Result#failure?`.
208
233
  ```ruby
209
234
  result = BCDD::Result::Failure(:err)
210
235
 
211
- result.failure? # true
212
- result.failure?(:err) # true
213
- result.failure?(:error) # false
236
+ result.failure?(:err)
237
+
238
+ # This is the same as:
239
+
240
+ result.failure? && result.type == :err
214
241
  ```
215
242
 
216
243
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
@@ -218,7 +245,7 @@ result.failure?(:error) # false
218
245
  ### Result Hooks
219
246
 
220
247
  Result hooks are methods that allow you to execute a block of code based on the type of result obtained.
221
- To demonstrate their use, I will implement a function that can divide two numbers.
248
+ To demonstrate their use, I will implement a method that can divide two numbers.
222
249
 
223
250
  ```ruby
224
251
  def divide(arg1, arg2)
@@ -282,8 +309,7 @@ result = divide(nil, 2)
282
309
 
283
310
  output =
284
311
  result
285
- .on_type(:invalid_arg) { |msg| puts msg }
286
- .on_type(:division_by_zero) { |msg| puts msg }
312
+ .on_type(:invalid_arg, :division_by_zero) { |msg| puts msg }
287
313
  .on_type(:division_completed) { |number| puts number }
288
314
 
289
315
  # The code above will print 'arg1 must be numeric' and return the result itself.
@@ -303,16 +329,18 @@ The `BCDD::Result#on_success` method is quite similar to the `BCDD::Result#on` h
303
329
  2. If the type declaration is not included, the method will execute the block for any successful result, regardless of its type.
304
330
 
305
331
  ```ruby
306
- # It executes the block and return itself.
332
+ # In both examples, it executes the block and returns the result itself.
307
333
 
308
334
  divide(4, 2).on_success { |number| puts number }
309
335
 
310
336
  divide(4, 2).on_success(:division_completed) { |number| puts number }
311
337
 
312
- # It doesn't execute the block, but return itself.
338
+ # It doesn't execute the block as the type is different.
313
339
 
314
340
  divide(4, 4).on_success(:ok) { |value| puts value }
315
341
 
342
+ # It doesn't execute the block, as the result is a success, but the hook expects a failure.
343
+
316
344
  divide(4, 4).on_failure { |error| puts error }
317
345
  ```
318
346
 
@@ -328,17 +356,19 @@ It is the opposite of `Result#on_success`:
328
356
  2. If the type declaration is not included, the method will execute the block for any failed result, regardless of its type.
329
357
 
330
358
  ```ruby
331
- # It executes the block and return itself.
359
+ # In both examples, it executes the block and returns the result itself.
332
360
 
333
361
  divide(nil, 2).on_failure { |error| puts error }
334
362
 
335
- divide(4, 0).on_failure(:invalid_arg, :division_by_zero) { |error| puts error }
363
+ divide(4, 0).on_failure(:division_by_zero) { |error| puts error }
336
364
 
337
- # It doesn't execute the block, but return itself.
338
-
339
- divide(4, 0).on_success { |number| puts number }
365
+ # It doesn't execute the block as the type is different.
340
366
 
341
367
  divide(4, 0).on_failure(:invalid_arg) { |error| puts error }
368
+
369
+ # It doesn't execute the block, as the result is a failure, but the hook expects a success.
370
+
371
+ divide(4, 0).on_success { |number| puts number }
342
372
  ```
343
373
 
344
374
  *PS: The `divide()` implementation is [here](#result-hooks).*
@@ -453,7 +483,7 @@ divide(100, 0).value_or { 0 } # 0
453
483
 
454
484
  #### `result.data`
455
485
 
456
- The `BCDD::Result#data` exposes the result attributes (name, type, value) directly and as a hash (`to_h`/`to_hash`) and array (`to_a`/`to_ary`).
486
+ The `BCDD::Result#data` exposes the result attributes (kind, type, value) directly and as a hash (`to_h`/`to_hash`) and array (`to_a`/`to_ary`).
457
487
 
458
488
  This is helpful if you need to access the result attributes generically or want to use Ruby features like splat (`*`) and double splat (`**`) operators.
459
489
 
@@ -462,25 +492,25 @@ See the examples below to understand how to use it.
462
492
  ```ruby
463
493
  result = BCDD::Result::Success(:ok, 1)
464
494
 
465
- success_data = result.data # #<BCDD::Result::Data name=:success type=:ok value=1>
495
+ success_data = result.data # #<BCDD::Result::Data kind=:success type=:ok value=1>
466
496
 
467
- success_data.name # :success
497
+ success_data.kind # :success
468
498
  success_data.type # :ok
469
499
  success_data.value # 1
470
500
 
471
- success_data.to_h # {:name=>:success, :type=>:ok, :value=>1}
501
+ success_data.to_h # {:kind=>:success, :type=>:ok, :value=>1}
472
502
  success_data.to_a # [:success, :ok, 1]
473
503
 
474
- name, type, value = success_data
504
+ kind, type, value = success_data
475
505
 
476
- [name, type, value] # [:success, :ok, 1]
506
+ [kind, type, value] # [:success, :ok, 1]
477
507
 
478
- def print_to_ary(name, type, value)
479
- puts [name, type, value].inspect
508
+ def print_to_ary(kind, type, value)
509
+ puts [kind, type, value].inspect
480
510
  end
481
511
 
482
- def print_to_hash(name:, type:, value:)
483
- puts [name, type, value].inspect
512
+ def print_to_hash(kind:, type:, value:)
513
+ puts [kind, type, value].inspect
484
514
  end
485
515
 
486
516
  print_to_ary(*success_data) # [:success, :ok, 1]
@@ -570,7 +600,7 @@ module Divide
570
600
 
571
601
  def call(arg1, arg2)
572
602
  validate_numbers(arg1, arg2)
573
- .and_then { |numbers| validate_non_zero(numbers) }
603
+ .and_then { |numbers| validate_nonzero(numbers) }
574
604
  .and_then { |numbers| divide(numbers) }
575
605
  end
576
606
 
@@ -583,8 +613,8 @@ module Divide
583
613
  BCDD::Result::Success(:ok, [arg1, arg2])
584
614
  end
585
615
 
586
- def validate_non_zero(numbers)
587
- return BCDD::Result::Success(:ok, numbers) unless numbers.last.zero?
616
+ def validate_nonzero(numbers)
617
+ return BCDD::Result::Success(:ok, numbers) if numbers.last.nonzero?
588
618
 
589
619
  BCDD::Result::Failure(:division_by_zero, 'arg2 must not be zero')
590
620
  end
@@ -615,9 +645,11 @@ Divide.call(2, 2)
615
645
 
616
646
  #### `BCDD::Result.mixin`
617
647
 
618
- This method generates a module that can be included or extended by any object. It adds two methods to the target object: `Success()` and `Failure()`. 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.
648
+ This method generates a module that any object can include or extend. It adds two methods to the target object: `Success()` and `Failure()`.
649
+
650
+ 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.
619
651
 
620
- As a result, you can utilize the `#and_then` method to invoke methods from the result's subject.
652
+ Because the result has a subject, the `#and_then` method can call methods from it.
621
653
 
622
654
  ##### Class example (Instance Methods)
623
655
 
@@ -634,7 +666,7 @@ class Divide
634
666
 
635
667
  def call
636
668
  validate_numbers
637
- .and_then(:validate_non_zero)
669
+ .and_then(:validate_nonzero)
638
670
  .and_then(:divide)
639
671
  end
640
672
 
@@ -649,7 +681,7 @@ class Divide
649
681
  Success(:ok, [arg1, arg2])
650
682
  end
651
683
 
652
- def validate_non_zero(numbers)
684
+ def validate_nonzero(numbers)
653
685
  return Success(:ok, numbers) unless numbers.last.zero?
654
686
 
655
687
  Failure(:division_by_zero, 'arg2 must not be zero')
@@ -675,7 +707,7 @@ module Divide
675
707
 
676
708
  def call(arg1, arg2)
677
709
  validate_numbers(arg1, arg2)
678
- .and_then(:validate_non_zero)
710
+ .and_then(:validate_nonzero)
679
711
  .and_then(:divide)
680
712
  end
681
713
 
@@ -688,7 +720,7 @@ module Divide
688
720
  Success(:ok, [arg1, arg2])
689
721
  end
690
722
 
691
- def validate_non_zero(numbers)
723
+ def validate_nonzero(numbers)
692
724
  return Success(:ok, numbers) unless numbers.last.zero?
693
725
 
694
726
  Failure(:division_by_zero, 'arg2 must not be zero')
@@ -717,7 +749,7 @@ If you try to use `BCDD::Result::Subject()`/`BCDD::Result::Failure()`, or result
717
749
  **Note:** You can still use the block syntax, but all the results must be produced by the subject's `Success()` and `Failure()` methods.
718
750
 
719
751
  ```ruby
720
- module ValidateNonZero
752
+ module ValidateNonzero
721
753
  extend self, BCDD::Result.mixin
722
754
 
723
755
  def call(numbers)
@@ -727,40 +759,83 @@ module ValidateNonZero
727
759
  end
728
760
  end
729
761
 
730
- class Divide
731
- include BCDD::Result.mixin
762
+ module Divide
763
+ extend self, BCDD::Result.mixin
732
764
 
733
- attr_reader :arg1, :arg2
765
+ def call(arg1, arg2)
766
+ validate_numbers(arg1, arg2)
767
+ .and_then(:validate_nonzero)
768
+ .and_then(:divide)
769
+ end
734
770
 
735
- def initialize(arg1, arg2)
736
- @arg1 = arg1
737
- @arg2 = arg2
771
+ private
772
+
773
+ def validate_numbers(arg1, arg2)
774
+ arg1.is_a?(::Numeric) or return Failure(:invalid_arg, 'arg1 must be numeric')
775
+ arg2.is_a?(::Numeric) or return Failure(:invalid_arg, 'arg2 must be numeric')
776
+
777
+ Success(:ok, [arg1, arg2])
738
778
  end
739
779
 
740
- def call
741
- validate_numbers
742
- .and_then(:validate_non_zero)
780
+ def validate_nonzero(numbers)
781
+ ValidateNonzero.call(numbers) # This will raise an error
782
+ end
783
+
784
+ def divide((number1, number2))
785
+ Success(:division_completed, number1 / number2)
786
+ end
787
+ end
788
+ ```
789
+
790
+ Look at the error produced by the code above:
791
+
792
+ ```ruby
793
+ Divide.call(2, 0)
794
+
795
+ # You cannot call #and_then and return a result that does not belong to the subject! (BCDD::Result::Error::InvalidResultSubject)
796
+ # Expected subject: Divide
797
+ # Given subject: ValidateNonzero
798
+ # Given result: #<BCDD::Result::Failure type=:division_by_zero value="arg2 must not be zero">
799
+ ```
800
+
801
+ In order to fix this, you must handle the result produced by `ValidateNonzero.call()` and return a result that belongs to the subject.
802
+
803
+ ```ruby
804
+ module ValidateNonzero
805
+ extend self, BCDD::Result.mixin
806
+
807
+ def call(numbers)
808
+ return Success(:ok, numbers) unless numbers.last.zero?
809
+
810
+ Failure(:division_by_zero, 'arg2 must not be zero')
811
+ end
812
+ end
813
+
814
+ module Divide
815
+ extend self, BCDD::Result.mixin
816
+
817
+ def call(arg1, arg2)
818
+ validate_numbers(arg1, arg2)
819
+ .and_then(:validate_nonzero)
743
820
  .and_then(:divide)
744
821
  end
745
822
 
746
823
  private
747
824
 
748
- def validate_numbers
749
- arg1.is_a?(::Numeric) or return BCDD::Result::Failure(:invalid_arg, 'arg1 must be numeric') # This will raise an error
825
+ def validate_numbers(arg1, arg2)
826
+ arg1.is_a?(::Numeric) or return Failure(:invalid_arg, 'arg1 must be numeric')
750
827
  arg2.is_a?(::Numeric) or return Failure(:invalid_arg, 'arg2 must be numeric')
751
828
 
752
- BCDD::Result::Success(:ok, [arg1, arg2]) # This will raise an error
829
+ Success(:ok, [arg1, arg2])
753
830
  end
754
831
 
755
- def validate_non_zero(numbers)
756
- ValidateNonZero.call(numbers) # This will raise an error
757
-
758
- # This would work:
832
+ def validate_nonzero(numbers)
759
833
  # In this case we are handling the other subject result and returning our own
760
- # ValidateNonZero.call(numbers).handle do |on|
761
- # on.success { |numbers| Success(:ok, numbers) }
762
- # on.failure { |err| Failure(:division_by_zero, err) }
763
- # end
834
+ ValidateNonzero.call(numbers).handle do |on|
835
+ on.success { |numbers| Success(:ok, numbers) }
836
+
837
+ on.failure { |err| Failure(:division_by_zero, err) }
838
+ end
764
839
  end
765
840
 
766
841
  def divide((number1, number2))
@@ -769,11 +844,20 @@ class Divide
769
844
  end
770
845
  ```
771
846
 
847
+ Look at the output of the code above:
848
+
849
+ ```ruby
850
+ Divide.call(2, 0)
851
+
852
+ #<BCDD::Result::Failure type=:division_by_zero value="arg2 must not be zero">
853
+ ```
854
+
772
855
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
773
856
 
774
857
  ##### Dependency Injection
775
858
 
776
- The `BCDD::Result#and_then` accepts a second argument that will be used to share a value with the subject's method. 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.
859
+ The `BCDD::Result#and_then` accepts a second argument that will be used to share a value with the subject's method.
860
+ 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.
777
861
 
778
862
  ```ruby
779
863
  require 'logger'
@@ -783,7 +867,7 @@ module Divide
783
867
 
784
868
  def call(arg1, arg2, logger: ::Logger.new(STDOUT))
785
869
  validate_numbers(arg1, arg2)
786
- .and_then(:validate_non_zero, logger)
870
+ .and_then(:validate_nonzero, logger)
787
871
  .and_then(:divide, logger)
788
872
  end
789
873
 
@@ -796,7 +880,7 @@ module Divide
796
880
  Success(:ok, [arg1, arg2])
797
881
  end
798
882
 
799
- def validate_non_zero(numbers, logger)
883
+ def validate_nonzero(numbers, logger)
800
884
  if numbers.last.zero?
801
885
  logger.error('arg2 must not be zero')
802
886
 
@@ -830,19 +914,21 @@ Divide.call(4, 2, logger: Logger.new(IO::NULL))
830
914
 
831
915
  ##### Add-ons
832
916
 
833
- The `BCDD::Result.mixin` also accepts the `with:` argument. It is a hash that will be used to define the methods that will be added to the target object.
917
+ The `BCDD::Result.mixin` also accepts the `config:` argument. It is a hash that will be used to define custom behaviors for the mixin.
834
918
 
835
- **Continue**
919
+ **continue**
836
920
 
837
- This addon will create the `Continue(value)` method, which will know how to produce a `Success(:continued, value)`. It is useful when you want to perform a sequence of operations but want to avoid returning a specific result for each step.
921
+ This addon will create the `Continue(value)` method and change the `Success()` behavior to halt the step chain.
922
+
923
+ So, if you want to advance to the next step, you must use `Continue(value)` instead of `Success(type, value)`. Otherwise, the step chain will be halted.
838
924
 
839
925
  ```ruby
840
926
  module Divide
841
- extend self, BCDD::Result.mixin(with: :Continue)
927
+ extend self, BCDD::Result.mixin(config: { addon: { continue: true } })
842
928
 
843
929
  def call(arg1, arg2)
844
930
  validate_numbers(arg1, arg2)
845
- .and_then(:validate_non_zero)
931
+ .and_then(:validate_nonzero)
846
932
  .and_then(:divide)
847
933
  end
848
934
 
@@ -855,7 +941,7 @@ module Divide
855
941
  Continue([arg1, arg2])
856
942
  end
857
943
 
858
- def validate_non_zero(numbers)
944
+ def validate_nonzero(numbers)
859
945
  return Continue(numbers) unless numbers.last.zero?
860
946
 
861
947
  Failure(:division_by_zero, 'arg2 must not be zero')
@@ -904,11 +990,11 @@ Look what happens if you try to create a result without one of the expected type
904
990
  ```ruby
905
991
  Divide::Result::Success(:ok)
906
992
  # type :ok is not allowed. Allowed types: :numbers, :division_completed
907
- # (BCDD::Result::Expectations::Error::UnexpectedType)
993
+ # (BCDD::Result::Contract::Error::UnexpectedType)
908
994
 
909
995
  Divide::Result::Failure(:err)
910
996
  # type :err is not allowed. Allowed types: :invalid_arg, :division_by_zero
911
- # (BCDD::Result::Expectations::Error::UnexpectedType)
997
+ # (BCDD::Result::Contract::Error::UnexpectedType)
912
998
  ```
913
999
 
914
1000
  The _**mixin mode**_ is similar to `BCDD::Result::Mixin`, but it also defines the expectations for the result's types and values.
@@ -922,7 +1008,7 @@ class Divide
922
1008
 
923
1009
  def call(arg1, arg2)
924
1010
  validate_numbers(arg1, arg2)
925
- .and_then(:validate_non_zero)
1011
+ .and_then(:validate_nonzero)
926
1012
  .and_then(:divide)
927
1013
  end
928
1014
 
@@ -935,7 +1021,7 @@ class Divide
935
1021
  Success(:numbers, [arg1, arg2])
936
1022
  end
937
1023
 
938
- def validate_non_zero(numbers)
1024
+ def validate_nonzero(numbers)
939
1025
  return Success(:numbers, numbers) unless numbers.last.zero?
940
1026
 
941
1027
  Failure(:division_by_zero, 'arg2 must not be zero')
@@ -947,10 +1033,10 @@ class Divide
947
1033
  end
948
1034
  ```
949
1035
 
950
- This mode also defines an `Expected` constant to be used inside and outside the module.
1036
+ This mode also defines an `Result` constant to be used inside and outside the module.
951
1037
 
952
1038
  > **PROTIP:**
953
- > You can use the `Expected` constant to mock the result's type and value in your tests. As they will have the exact expectations, your tests will check if the result clients are handling the result correctly.
1039
+ > You can use the `Result` constant to mock the result's type and value in your tests. As they will have the exact expectations, your tests will check if the result clients are handling the result correctly.
954
1040
 
955
1041
  Now that you know the two modes, let's understand how expectations can be beneficial and powerful for defining contracts.
956
1042
 
@@ -975,7 +1061,7 @@ result.success?(:division_completed) # true
975
1061
 
976
1062
  result.success?(:ok)
977
1063
  # type :ok is not allowed. Allowed types: :numbers, :division_completed
978
- # (BCDD::Result::Expectations::Error::UnexpectedType)
1064
+ # (BCDD::Result::Contract::Error::UnexpectedType)
979
1065
  ```
980
1066
 
981
1067
  **Failure example:**
@@ -989,7 +1075,7 @@ result.failure?(:division_by_zero) # false
989
1075
 
990
1076
  result.failure?(:err)
991
1077
  # type :err is not allowed. Allowed types: :invalid_arg, :division_by_zero
992
- # (BCDD::Result::Expectations::Error::UnexpectedType)
1078
+ # (BCDD::Result::Contract::Error::UnexpectedType)
993
1079
  ```
994
1080
 
995
1081
  *PS: The `Divide` implementation is [here](#standalone-versus-mixin-mode).*
@@ -1011,7 +1097,7 @@ result
1011
1097
 
1012
1098
  result.on(:number) { |_| :this_type_does_not_exist }
1013
1099
  # type :number is not allowed. Allowed types: :numbers, :division_completed, :invalid_arg, :division_by_zero
1014
- # (BCDD::Result::Expectations::Error::UnexpectedType)
1100
+ # (BCDD::Result::Contract::Error::UnexpectedType)
1015
1101
  ```
1016
1102
 
1017
1103
  *PS: The `Divide` implementation is [here](#standalone-versus-mixin-mode).*
@@ -1037,11 +1123,11 @@ result
1037
1123
 
1038
1124
  result.on_success(:ok) { |_| :this_type_does_not_exist }
1039
1125
  # type :ok is not allowed. Allowed types: :numbers, :division_completed
1040
- # (BCDD::Result::Expectations::Error::UnexpectedType)
1126
+ # (BCDD::Result::Contract::Error::UnexpectedType)
1041
1127
 
1042
1128
  result.on_failure(:err) { |_| :this_type_does_not_exist }
1043
1129
  # type :err is not allowed. Allowed types: :invalid_arg, :division_by_zero
1044
- # (BCDD::Result::Expectations::Error::UnexpectedType)
1130
+ # (BCDD::Result::Contract::Error::UnexpectedType)
1045
1131
  ```
1046
1132
 
1047
1133
  *PS: The `Divide` implementation is [here](#standalone-versus-mixin-mode).*
@@ -1058,17 +1144,17 @@ result = Divide.call(10, 2)
1058
1144
  result.handle do |on|
1059
1145
  on.type(:ok) { |_| :this_type_does_not_exist }
1060
1146
  end
1061
- # type :ok is not allowed. Allowed types: :numbers, :division_completed, :invalid_arg, :division_by_zero (BCDD::Result::Expectations::Error::UnexpectedType)
1147
+ # type :ok is not allowed. Allowed types: :numbers, :division_completed, :invalid_arg, :division_by_zero (BCDD::Result::Contract::Error::UnexpectedType)
1062
1148
 
1063
1149
  result.handle do |on|
1064
1150
  on.success(:ok) { |_| :this_type_does_not_exist }
1065
1151
  end
1066
- # type :ok is not allowed. Allowed types: :numbers, :division_completed (BCDD::Result::Expectations::Error::UnexpectedType)
1152
+ # type :ok is not allowed. Allowed types: :numbers, :division_completed (BCDD::Result::Contract::Error::UnexpectedType)
1067
1153
 
1068
1154
  result.handle do |on|
1069
1155
  on.failure(:err) { |_| :this_type_does_not_exist }
1070
1156
  end
1071
- # type :err is not allowed. Allowed types: :numbers, :division_completed (BCDD::Result::Expectations::Error::UnexpectedType)
1157
+ # type :err is not allowed. Allowed types: :invalid_arg, :division_by_zero (BCDD::Result::Contract::Error::UnexpectedType)
1072
1158
  ```
1073
1159
 
1074
1160
  *PS: The `Divide` implementation is [here](#standalone-versus-mixin-mode).*
@@ -1099,11 +1185,11 @@ end
1099
1185
 
1100
1186
  Divide.call('4', 2)
1101
1187
  # type :invalid_arg is not allowed. Allowed types: :err
1102
- # (BCDD::Result::Expectations::Error::UnexpectedType)
1188
+ # (BCDD::Result::Contract::Error::UnexpectedType)
1103
1189
 
1104
1190
  Divide.call(4, 2)
1105
1191
  # type :division_completed is not allowed. Allowed types: :ok
1106
- # (BCDD::Result::Expectations::Error::UnexpectedType)
1192
+ # (BCDD::Result::Contract::Error::UnexpectedType)
1107
1193
  ```
1108
1194
 
1109
1195
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
@@ -1126,11 +1212,11 @@ end
1126
1212
 
1127
1213
  Divide.call('4', 2)
1128
1214
  # type :invalid_arg is not allowed. Allowed types: :err
1129
- # (BCDD::Result::Expectations::Error::UnexpectedType)
1215
+ # (BCDD::Result::Contract::Error::UnexpectedType)
1130
1216
 
1131
1217
  Divide.call(4, 2)
1132
1218
  # type :division_completed is not allowed. Allowed types: :ok
1133
- # (BCDD::Result::Expectations::Error::UnexpectedType)
1219
+ # (BCDD::Result::Contract::Error::UnexpectedType)
1134
1220
  ```
1135
1221
 
1136
1222
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
@@ -1201,26 +1287,26 @@ The value validation will only be performed through the methods `Success()` and
1201
1287
 
1202
1288
  ```ruby
1203
1289
  Divide::Result::Success(:ok)
1204
- # type :ok is not allowed. Allowed types: :numbers, :division_completed (BCDD::Result::Expectations::Error::UnexpectedType)
1290
+ # type :ok is not allowed. Allowed types: :numbers, :division_completed (BCDD::Result::Contract::Error::UnexpectedType)
1205
1291
 
1206
1292
  Divide::Result::Success(:numbers, [1])
1207
- # value [1] is not allowed for :numbers type (BCDD::Result::Expectations::Error::UnexpectedValue)
1293
+ # value [1] is not allowed for :numbers type (BCDD::Result::Contract::Error::UnexpectedValue)
1208
1294
 
1209
1295
  Divide::Result::Success(:division_completed, '2')
1210
- # value "2" is not allowed for :division_completed type (BCDD::Result::Expectations::Error::UnexpectedValue)
1296
+ # value "2" is not allowed for :division_completed type (BCDD::Result::Contract::Error::UnexpectedValue)
1211
1297
  ```
1212
1298
 
1213
1299
  ##### Failure()
1214
1300
 
1215
1301
  ```ruby
1216
1302
  Divide::Result::Failure(:err)
1217
- # type :err is not allowed. Allowed types: :invalid_arg, :division_by_zero (BCDD::Result::Expectations::Error::UnexpectedType)
1303
+ # type :err is not allowed. Allowed types: :invalid_arg, :division_by_zero (BCDD::Result::Contract::Error::UnexpectedType)
1218
1304
 
1219
1305
  Divide::Result::Failure(:invalid_arg, :arg1_must_be_numeric)
1220
- # value :arg1_must_be_numeric is not allowed for :invalid_arg type (BCDD::Result::Expectations::Error::UnexpectedValue)
1306
+ # value :arg1_must_be_numeric is not allowed for :invalid_arg type (BCDD::Result::Contract::Error::UnexpectedValue)
1221
1307
 
1222
1308
  Divide::Result::Failure(:division_by_zero, msg: 'arg2 must not be zero')
1223
- # value {:msg=>"arg2 must not be zero"} is not allowed for :division_by_zero type (BCDD::Result::Expectations::Error::UnexpectedValue)
1309
+ # value {:msg=>"arg2 must not be zero"} is not allowed for :division_by_zero type (BCDD::Result::Contract::Error::UnexpectedValue)
1224
1310
  ```
1225
1311
 
1226
1312
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
@@ -1231,21 +1317,14 @@ The value checking has support for handling pattern-matching errors, and the cle
1231
1317
 
1232
1318
  How does this operator work? They raise an error when the pattern does not match but returns nil when it matches.
1233
1319
 
1234
- Because of this, you will need to enable `nil` as a valid value checking. You can do it by calling the `BCDD::Result::Contract.nil_as_valid_value_checking!` method.
1235
-
1236
- **Attention:**
1237
-
1238
- If you decide to enable this, you will do it at the beginning of your code or in an initializer. And remember, this will affect all kinds of result expectations (`BCDD::Result::Expectations` and `BCDD::Result::Context::Expectations`). So, it is recommended to use it only when you are using pattern matching for **ALL** the result's value validations.
1320
+ Because of this, you will need to enable `nil` as a valid value checking. You can do it through the `BCDD::Result.configuration` or by allowing it directly on the mixin config.
1239
1321
 
1240
1322
  ```ruby
1241
- #
1242
- # Put this line in an initializer or at the beginning of your code.
1243
- # It is required if you decide to use pattern matching to validate all of your result's values.
1244
- #
1245
- BCDD::Result::Contract.nil_as_valid_value_checking!
1246
-
1247
1323
  module Divide
1248
1324
  extend BCDD::Result::Expectations.mixin(
1325
+ config: {
1326
+ pattern_matching: { nil_as_valid_value_checking: true }
1327
+ },
1249
1328
  success: {
1250
1329
  division_completed: ->(value) { value => (Integer | Float) }
1251
1330
  },
@@ -1263,30 +1342,32 @@ module Divide
1263
1342
  end
1264
1343
 
1265
1344
  Divide.call(10, 5)
1266
- # value "5" is not allowed for :division_completed type ("5": Float === "5" does not return true) (BCDD::Result::Contract::Error::UnexpectedValue)
1345
+ # value "2" is not allowed for :division_completed type ("2": Float === "2" does not return true) (BCDD::Result::Contract::Error::UnexpectedValue)
1267
1346
  ```
1268
1347
 
1269
1348
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1270
1349
 
1271
1350
  #### `BCDD::Result::Expectations.mixin` add-ons
1272
1351
 
1273
- The `BCDD::Result::Expectations.mixin` also accepts the `with:` argument. It is a hash that will be used to define the methods that will be added to the target object.
1352
+ The `BCDD::Result::Expectations.mixin` also accepts the `config:` argument. It is a hash that can be used to define custom behaviors for the mixin.
1274
1353
 
1275
1354
  **Continue**
1276
1355
 
1277
- It is similar to `BCDD::Result.mixin(with: :Continue)`, the key difference is that the `Continue(value)` will be ignored by the expectations. This is extremely useful when you want to use `Continue(value)` to chain operations, but you don't want to declare N success types in the expectations.
1356
+ It is similar to `BCDD::Result.mixin(config: { addon: { continue: true } })`. The key difference is that the expectations will ignore the `Continue(value)`.
1357
+
1358
+ Based on this, use the `Success()` to produce a terminal result and `Continue()` to produce a result that will be used in the next step.
1278
1359
 
1279
1360
  ```ruby
1280
1361
  class Divide
1281
1362
  include BCDD::Result::Expectations.mixin(
1282
- with: :Continue,
1363
+ config: { addon: { continue: true } },
1283
1364
  success: :division_completed,
1284
1365
  failure: %i[invalid_arg division_by_zero]
1285
1366
  )
1286
1367
 
1287
1368
  def call(arg1, arg2)
1288
1369
  validate_numbers(arg1, arg2)
1289
- .and_then(:validate_non_zero)
1370
+ .and_then(:validate_nonzero)
1290
1371
  .and_then(:divide)
1291
1372
  end
1292
1373
 
@@ -1299,7 +1380,7 @@ class Divide
1299
1380
  Continue([arg1, arg2])
1300
1381
  end
1301
1382
 
1302
- def validate_non_zero(numbers)
1383
+ def validate_nonzero(numbers)
1303
1384
  return Continue(numbers) unless numbers.last.zero?
1304
1385
 
1305
1386
  Failure(:division_by_zero, 'arg2 must not be zero')
@@ -1310,7 +1391,7 @@ class Divide
1310
1391
  end
1311
1392
  end
1312
1393
 
1313
- result = Divide.new.call(4,2)
1394
+ result = Divide.new.call(4, 2)
1314
1395
  # => #<BCDD::Result::Success type=:division_completed value=2>
1315
1396
 
1316
1397
  # The example below shows an error because the :ok type is not allowed.
@@ -1318,7 +1399,7 @@ result = Divide.new.call(4,2)
1318
1399
  # This is because the :continued type is ignored by the expectations.
1319
1400
  #
1320
1401
  result.success?(:ok)
1321
- # type :ok is not allowed. Allowed types: :division_completed (BCDD::Result::Expectations::Error::UnexpectedType)
1402
+ # type :ok is not allowed. Allowed types: :division_completed (BCDD::Result::Contract::Error::UnexpectedType)
1322
1403
  ```
1323
1404
 
1324
1405
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
@@ -1359,6 +1440,22 @@ BCDD::Result::Context::Success(:ok, **{ message: 'hashes can be converted to key
1359
1440
 
1360
1441
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1361
1442
 
1443
+ #### Constant aliases
1444
+
1445
+ You can configure `Context` or `BCDD::Context` as an alias for `BCDD::Result::Context`. This is helpful to define a standard way to avoid the full constant name/path in your code.
1446
+
1447
+ ```ruby
1448
+ BCDD::Result.configuration do |config|
1449
+ config.context_alias.enable!('BCDD::Context')
1450
+
1451
+ # or
1452
+
1453
+ config.context_alias.enable!('Context')
1454
+ end
1455
+ ```
1456
+
1457
+ <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1458
+
1362
1459
  #### `BCDD::Result::Context.mixin`
1363
1460
 
1364
1461
  As in the `BCDD::Result`, you can use the `BCDD::Result::Context.mixin` to add the `Success()` and `Failure()` methods to your classes/modules.
@@ -1368,14 +1465,14 @@ Let's see this feature and the data accumulation in action:
1368
1465
  ##### Class example (Instance Methods)
1369
1466
 
1370
1467
  ```ruby
1371
- class Divide
1372
- require 'logger'
1468
+ require 'logger'
1373
1469
 
1470
+ class Divide
1374
1471
  include BCDD::Result::Context.mixin
1375
1472
 
1376
1473
  def call(arg1, arg2, logger: ::Logger.new(STDOUT))
1377
1474
  validate_numbers(arg1, arg2)
1378
- .and_then(:validate_non_zero)
1475
+ .and_then(:validate_nonzero)
1379
1476
  .and_then(:divide, logger: logger)
1380
1477
  end
1381
1478
 
@@ -1388,7 +1485,7 @@ class Divide
1388
1485
  Success(:ok, number1: arg1, number2: arg2)
1389
1486
  end
1390
1487
 
1391
- def validate_non_zero(number2:, **)
1488
+ def validate_nonzero(number2:, **)
1392
1489
  return Success(:ok) if number2.nonzero?
1393
1490
 
1394
1491
  Failure(:err, message: 'arg2 must not be zero')
@@ -1434,8 +1531,9 @@ class Divide
1434
1531
 
1435
1532
  def call(arg1, arg2)
1436
1533
  validate_numbers(arg1, arg2)
1437
- .and_then(:validate_non_zero)
1534
+ .and_then(:validate_nonzero)
1438
1535
  .and_then(:divide)
1536
+ .and_expose(:division_completed, [:number])
1439
1537
  end
1440
1538
 
1441
1539
  private
@@ -1447,7 +1545,7 @@ class Divide
1447
1545
  Success(:ok, number1: arg1, number2: arg2)
1448
1546
  end
1449
1547
 
1450
- def validate_non_zero(number2:, **)
1548
+ def validate_nonzero(number2:, **)
1451
1549
  return Success(:ok) if number2.nonzero?
1452
1550
 
1453
1551
  Failure(:err, message: 'arg2 must not be zero')
@@ -1483,7 +1581,7 @@ module Divide
1483
1581
 
1484
1582
  def call(arg1, arg2)
1485
1583
  validate_numbers(arg1, arg2)
1486
- .and_then(:validate_non_zero)
1584
+ .and_then(:validate_nonzero)
1487
1585
  .and_then(:divide)
1488
1586
  .and_expose(:division_completed, [:number])
1489
1587
  end
@@ -1497,7 +1595,7 @@ module Divide
1497
1595
  Success(:ok, number1: arg1, number2: arg2)
1498
1596
  end
1499
1597
 
1500
- def validate_non_zero(number2:, **)
1598
+ def validate_nonzero(number2:, **)
1501
1599
  return Success(:ok) if number2.nonzero?
1502
1600
 
1503
1601
  Failure(:err, message: 'arg2 must not be zero')
@@ -1530,14 +1628,11 @@ The `BCDD::Result::Context::Expectations` is a `BCDD::Result::Expectations` with
1530
1628
  This is an example using the mixin mode, but the standalone mode is also supported.
1531
1629
 
1532
1630
  ```ruby
1533
- #
1534
- # Put this line in an initializer or at the beginning of your code.
1535
- # It is required if you decide to use pattern matching to validate all of your result's values.
1536
- #
1537
- BCDD::Result::Contract.nil_as_valid_value_checking!
1538
-
1539
1631
  class Divide
1540
1632
  include BCDD::Result::Context::Expectations.mixin(
1633
+ config: {
1634
+ pattern_matching: { nil_as_valid_value_checking: true }
1635
+ },
1541
1636
  success: {
1542
1637
  division_completed: ->(value) { value => { number: Numeric } }
1543
1638
  },
@@ -1553,7 +1648,7 @@ class Divide
1553
1648
 
1554
1649
  arg2.zero? and return Failure(:division_by_zero, message: 'arg2 must not be zero')
1555
1650
 
1556
- Success(:division_completed, number: arg1 / arg2)
1651
+ Success(:division_completed, number: (arg1 / arg2))
1557
1652
  end
1558
1653
  end
1559
1654
 
@@ -1577,26 +1672,25 @@ Divide::Result::Success(:division_completed, number: '2')
1577
1672
 
1578
1673
  #### Mixin add-ons
1579
1674
 
1580
- The `BCDD::Result::Context.mixin` and `BCDD::Result::Context::Expectations.mixin` also accepts the `with:` argument. And it works the same way as the `BCDD::Result` mixins.
1675
+ The `BCDD::Result::Context.mixin` and `BCDD::Result::Context::Expectations.mixin` also accepts the `config:` argument. And it works the same way as the `BCDD::Result` mixins.
1581
1676
 
1582
1677
  **Continue**
1583
1678
 
1584
- The `BCDD::Result::Context.mixin(with: :Continue)` or `BCDD::Result::Context::Expectations.mixin(with: :Continue)` adds a `Continue(**input)` that will be ignored by the expectations. This is extremely useful when you want to use `Continue()` to chain operations, but you don't want to declare N success types in the expectations.
1679
+ The `BCDD::Result::Context.mixin(config: { addon: { continue: true } })` or `BCDD::Result::Context::Expectations.mixin(config: { addon: { continue: true } })` creates the `Continue(value)` method and change the `Success()` behavior to halt the step chain.
1680
+
1681
+ So, if you want to advance to the next step, you must use `Continue(**value)` instead of `Success(type, **value)`. Otherwise, the step chain will be halted.
1585
1682
 
1586
1683
  Let's use a mix of `BCDD::Result::Context` features to see in action with this add-on:
1587
1684
 
1588
1685
  ```ruby
1589
- #
1590
- # Put this line in an initializer or at the beginning of your code.
1591
- # It is required if you decide to use pattern matching to validate all of your result's values.
1592
- #
1593
- BCDD::Result::Contract.nil_as_valid_value_checking!
1594
-
1595
1686
  module Divide
1596
1687
  require 'logger'
1597
1688
 
1598
1689
  extend self, BCDD::Result::Context::Expectations.mixin(
1599
- with: :Continue,
1690
+ config: {
1691
+ addon: { continue: true },
1692
+ pattern_matching: { nil_as_valid_value_checking: true }
1693
+ },
1600
1694
  success: {
1601
1695
  division_completed: ->(value) { value => { number: Numeric } }
1602
1696
  },
@@ -1608,7 +1702,7 @@ module Divide
1608
1702
 
1609
1703
  def call(arg1, arg2, logger: ::Logger.new(STDOUT))
1610
1704
  validate_numbers(arg1, arg2)
1611
- .and_then(:validate_non_zero)
1705
+ .and_then(:validate_nonzero)
1612
1706
  .and_then(:divide, logger: logger)
1613
1707
  .and_expose(:division_completed, [:number])
1614
1708
  end
@@ -1622,7 +1716,7 @@ module Divide
1622
1716
  Continue(number1: arg1, number2: arg2)
1623
1717
  end
1624
1718
 
1625
- def validate_non_zero(number2:, **)
1719
+ def validate_nonzero(number2:, **)
1626
1720
  return Continue() if number2.nonzero?
1627
1721
 
1628
1722
  Failure(:division_by_zero, message: 'arg2 must not be zero')
@@ -1651,8 +1745,122 @@ Divide.call(14, 0)
1651
1745
  #<BCDD::Result::Context::Failure type=:division_by_zero value={:message=>"arg2 must not be zero"}>
1652
1746
  ```
1653
1747
 
1748
+ ### `BCDD::Result.configuration`
1749
+
1750
+ The `BCDD::Result.configuration` allows you to configure default behaviors for `BCDD::Result` and `BCDD::Result::Context` through a configuration block. After using it, the configuration is frozen, ensuring the expected behaviors for your application.
1751
+
1752
+ ```ruby
1753
+ BCDD::Result.configuration do |config|
1754
+ config.addon.enable!(:continue)
1755
+
1756
+ config.constant_alias.enable!('Result', 'BCDD::Context')
1757
+
1758
+ config.pattern_matching.disable!(:nil_as_valid_value_checking)
1759
+
1760
+ # config.feature.disable!(:expectations) if ::Rails.env.production?
1761
+ end
1762
+ ```
1763
+
1764
+ Use `disable!` to disable a feature and `enable!` to enable it.
1765
+
1766
+ Let's see what each configuration in the example above does:
1767
+
1768
+ #### `config.addon.enable!(:continue)`
1769
+
1770
+ This configuration enables the `Continue()` method for `BCDD::Result`, `BCDD::Result::Context`, `BCDD::Result::Expectation`, and `BCDD::Result::Context::Expectation`. Link to documentations: [(1)](#add-ons) [(2)](#mixin-add-ons).
1771
+
1772
+ #### `config.constant_alias.enable!('Result', 'BCDD::Context')`
1773
+
1774
+ This configuration make `Result` a constant alias for `BCDD::Result`, and `BCDD::Context` a constant alias for `BCDD::Result::Context`.
1775
+
1776
+ Link to documentations:
1777
+ - [Result alias](#bcddresult-versus-result)
1778
+ - [Context aliases](#constant-aliases)
1779
+
1780
+ #### `config.pattern_matching.disable!(:nil_as_valid_value_checking)`
1781
+
1782
+ This configuration disables the `nil_as_valid_value_checking` for `BCDD::Result` and `BCDD::Result::Context`. Link to [documentation](#pattern-matching-support).
1783
+
1654
1784
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1655
1785
 
1786
+ #### `config.feature.disable!(:expectations)`
1787
+
1788
+ This configuration turns off the expectations for `BCDD::Result` and `BCDD::Result::Context`. The expectations are helpful in development and test environments, but they can be disabled in production environments for performance gain.
1789
+
1790
+ PS: I'm using `::Rails.env.production?` to check the environment, but you can use any logic you want.
1791
+
1792
+ ### `BCDD::Result.config`
1793
+
1794
+ The `BCDD::Result.config` allows you to access the current configuration. It is useful when you want to check the current configuration.
1795
+
1796
+ **BCDD::Result.config.addon**
1797
+
1798
+ ```ruby
1799
+ BCDD::Result.config.addon.enabled?(:continue)
1800
+
1801
+ BCDD::Result.config.addon.options
1802
+ # {
1803
+ # :continue=>{
1804
+ # :enabled=>false,
1805
+ # :affects=>[
1806
+ # "BCDD::Result",
1807
+ # "BCDD::Result::Context",
1808
+ # "BCDD::Result::Expectations",
1809
+ # "BCDD::Result::Context::Expectations"
1810
+ # ]
1811
+ # }
1812
+ # }
1813
+ ```
1814
+
1815
+ **BCDD::Result.config.constant_alias**
1816
+
1817
+ ```ruby
1818
+ BCDD::Result.config.constant_alias.enabled?('Result')
1819
+ BCDD::Result.config.constant_alias.enabled?('Context')
1820
+ BCDD::Result.config.constant_alias.enabled?('BCDD::Context')
1821
+
1822
+ BCDD::Result.config.constant_alias.options
1823
+ # {
1824
+ # "Result"=>{:enabled=>false, :affects=>["Object"]},
1825
+ # "Context"=>{:enabled=>false, :affects=>["Object"]},
1826
+ # "BCDD::Context"=>{:enabled=>false, :affects=>["BCDD"]}
1827
+ # }
1828
+ ```
1829
+
1830
+ **BCDD::Result.config.pattern_matching**
1831
+
1832
+ ```ruby
1833
+ BCDD::Result.config.pattern_matching.enabled?(:nil_as_valid_value_checking)
1834
+
1835
+ BCDD::Result.config.pattern_matching.options
1836
+ # {
1837
+ # :nil_as_valid_value_checking=>{
1838
+ # :enabled=>false,
1839
+ # :affects=>[
1840
+ # "BCDD::Result::Expectations,
1841
+ # "BCDD::Result::Context::Expectations"
1842
+ # ]
1843
+ # }
1844
+ # }
1845
+ ```
1846
+
1847
+ **BCDD::Result.config.feature**
1848
+
1849
+ ```ruby
1850
+ BCDD::Result.config.feature.enabled?(:expectations)
1851
+
1852
+ BCDD::Result.config.feature.options
1853
+ # {
1854
+ # :expectations=>{
1855
+ # :enabled=>true,
1856
+ # :affects=>[
1857
+ # "BCDD::Result::Expectations,
1858
+ # "BCDD::Result::Context::Expectations"
1859
+ # ]
1860
+ # }
1861
+ # }
1862
+ ```
1863
+
1656
1864
  ## About
1657
1865
 
1658
1866
  [Rodrigo Serradura](https://github.com/serradura) created this project. He is the B/CDD process/method creator and has already made similar gems like the [u-case](https://github.com/serradura/u-case) and [kind](https://github.com/serradura/kind/blob/main/lib/kind/result.rb). This gem is a general-purpose abstraction/monad, but it also contains key features that serve as facilitators for adopting B/CDD in the code.