cuprum 0.7.0 → 0.8.0

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
  SHA1:
3
- metadata.gz: 8d393a222eda76e4b943c721df4a4d54c89966e9
4
- data.tar.gz: d0e9efa6075c9346114ecb02883b380621873510
3
+ metadata.gz: cafecaeff8b2c0209616cd9303613d88723c2477
4
+ data.tar.gz: b4d1c2cdde687815ac835631c460a45d15a3306d
5
5
  SHA512:
6
- metadata.gz: 196f5f4472c76d664f4d6b8764503a7fee5fabae50061edc877d1cc060421b05067861c96fc654a8a2586911c318b6ff9d65e515c299ffaed647f9742021dd88
7
- data.tar.gz: c1cd4f744cdfb37493f100de095ef89d1e3c080ae59f99af76ca43c69f8aaeaf14cfddc9068a824956da2e19aed4017bb70e6bb6d608969ea6e4acc5f096f875
6
+ metadata.gz: f465ecb20dd65d5e835f6f506bbaca272e39637a5b127fac31929fef88a880069ed8b7f86802b207b01b767de952d641a688344dfabd8b1d4347d904daf926d7
7
+ data.tar.gz: be12f0a8d8be45ba1aabc854b48be53be13e2716d39e1c48fecae038b99019880c19686fd96bb1d1ff04272400650723df47b789ebe48b60da1e6ba844175f3a
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0
4
+
5
+ The "We Have The Technology" Update.
6
+
7
+ ### Commands
8
+
9
+ Added protected chaining methods `#chain!`, `#tap_result!` and `#yield_result!`. These methods function as their non-imperative counterparts, but add the chained command or block to the current command instead of a clone.
10
+
11
+ Removed the ResultHelpers mixin from the default Command class. To use the result helper methods, include Cuprum::ResultHelpers in your command class.
12
+
13
+ Removed the #build_errors helper - each Result is now responsible for building its own errors object. To use a custom errors object, define a subclass of Cuprum::Result and override its #build_errors method, then update your Command's #build_result method to use your custom result class.
14
+
15
+ ### Command Factory
16
+
17
+ Implemented the CommandFactory class, which provides a builder interface and DSL for grouping and creating commands with a common purpose or with shared configuration.
18
+
3
19
  ## 0.7.0
4
20
 
5
21
  The "To Strive, To Seek, To Find, And Not To Yield" Update.
@@ -1,43 +1,36 @@
1
1
  # Development
2
2
 
3
- ## Version 1.0.0+
3
+ ## Version 0.9.0
4
4
 
5
- 'The "Look On My Works, Ye Mighty, and Despair" Update'
5
+ The "Second Star To The Right" Update
6
6
 
7
- - Integration specs.
8
- - Configuration option to raise, warn, ignore discarded results.
7
+ ### Actions
8
+
9
+ #### LifecycleHooks
10
+
11
+ - :before, :after hooks
12
+ - NOT included in Command by default
13
+
14
+ ## Version 0.10.0
15
+
16
+ 'The "Out Of Context Problem" Update'
9
17
 
10
18
  ### Commands
11
19
 
12
- - Protected Chaining Methods:
13
- - #chain!, #success!, #failure!, #tap_chain!, #yield_result!
14
- - adds chained command to current command instead of a clone.
15
- - Command#to_proc
16
- - :clear_errors => true option on #chain
17
20
  - #context object
18
- - command currying
19
21
 
20
- #### Cuprum::DSL
22
+ ## Version 1.0.0
21
23
 
22
- - ::process - shortcut for defining #process
23
- - ::rescue - `rescue StandardError do ... end`, rescues matched errors in #process
24
- - chaining methods:
25
- - ::chain (::success, ::failure):
26
- on #initialize, chains the given command. Can be given a command class
27
- (if ::new takes no arguments) or a block that returns a command.
28
- - constructor methods:
29
- - Programmatically generate a constructor method. Raises an error if
30
- #initialize is defined. Automatically sets instance variables on initialize,
31
- and defines reader methods.
32
- - ::arguments - sets all positional arguments in the constructor. Takes 0 or
33
- more String or Symbol arguments representing required arguments. Takes an
34
- optional hash with String/Symbol keys and arbitrary values, representing
35
- optional arguments and their default values.
36
- - ::keywords - sets keyword arguments; same arguments as ::arguments.
24
+ 'The "Look On My Works, Ye Mighty, and Despair" Update'
37
25
 
38
- #### Hooks
26
+ - Integration specs.
27
+ - Configuration option to raise, warn, ignore discarded results.
28
+ - Code cleanup: Hash syntax, remove end comments, remove file headers
29
+
30
+ ### Commands
39
31
 
40
- - :before, :around, :after hooks
32
+ - Command#to_proc
33
+ - :clear_errors => true option on #chain
41
34
 
42
35
  ### Commands - Built In
43
36
 
@@ -45,19 +38,6 @@
45
38
  as array
46
39
  - RetryCommand
47
40
 
48
- ### CommandFactory
49
-
50
- - builder/aggregator for command objects, esp. with shared
51
- initializers/parameters, e.g. actions for a resource
52
- - Syntax: |
53
-
54
- actions = ResourceCommandFactory.new(Book)
55
- command = actions::Build.new #=> returns a book builder command
56
- result = command.call(attributes) #=> returns a result with value => a Book
57
- # OR
58
- result = actions.build(attributes) #=> returns a result with value => a Book
59
- book = result.value
60
-
61
41
  ### Documentation
62
42
 
63
43
  Chaining Case Study: |
@@ -73,3 +53,29 @@ Chaining Case Study: |
73
53
  Create Content
74
54
  Create ContentVersion
75
55
  Tags.each { FindOrCreate Tag }
56
+
57
+ ## Future Versions
58
+
59
+ ### Commands
60
+
61
+ - command currying
62
+
63
+ #### Cuprum::DSL
64
+
65
+ - ::process - shortcut for defining #process
66
+ - ::rescue - `rescue StandardError do ... end`, rescues matched errors in #process
67
+ - chaining methods:
68
+ - ::chain (::success, ::failure):
69
+ on #initialize, chains the given command. Can be given a command class
70
+ (if ::new takes no arguments) or a block that returns a command.
71
+ - constructor methods:
72
+ - Programmatically generate a constructor method. Raises an error if
73
+ #initialize is defined. Automatically sets instance variables on initialize,
74
+ and defines reader methods.
75
+ - ::arguments - sets all positional arguments in the constructor. Takes 0 or
76
+ more String or Symbol arguments representing required arguments. Takes an
77
+ optional hash with String/Symbol keys and arbitrary values, representing
78
+ optional arguments and their default values.
79
+ - ::keywords - sets keyword arguments; same arguments as ::arguments.
80
+
81
+ #### Hooks
data/README.md CHANGED
@@ -31,7 +31,7 @@ If you want to extract your logic but Cuprum is not the right solution for you,
31
31
 
32
32
  ### Compatibility
33
33
 
34
- Cuprum is tested against Ruby (MRI) 2.4.
34
+ Cuprum is tested against Ruby (MRI) 2.3 through 2.5.
35
35
 
36
36
  ### Documentation
37
37
 
@@ -650,6 +650,43 @@ result.success? #=> true
650
650
 
651
651
  Under the hood, both `#chain` and `#tap_result` are implemented on top of `#yield_result`.
652
652
 
653
+ #### Protected Chaining Methods
654
+
655
+ Each Command also defines the `#chain!`, `#tap_result!`, and `#yield_result!` methods - note the imperative `!`. These methods behave identically to their non-imperative counterparts, but they modify the current command directly instead of creating a clone. They are also protected methods, so they cannot be called from outside the command itself. These methods are designed for use when defining commands.
656
+
657
+ ```ruby
658
+ # We subclass the build command, which will be executed first.
659
+ class CreateCommentCommand < BuildCommentCommand
660
+ include Cuprum::Chaining
661
+ include Cuprum::Processing
662
+ #
663
+ def initialize
664
+ # After the build step is run, we validate the comment.
665
+ chain!(ValidateCommentCommand.new)
666
+ #
667
+ # If the validation passes, we then save the comment.
668
+ chain!(SaveCommentCommand.new, on: :success)
669
+ end
670
+ end
671
+
672
+ Comment.count #=> 0
673
+
674
+ body = 'Why do hot dogs come in packages of ten, and hot dog buns come in ' \
675
+ 'packages of eight?'
676
+ result = CreateCommentCommand.new.call({ user_id: '12345', body: body })
677
+
678
+ result.value #=> an instance of Comment with the given user_id and body.
679
+ result.success? #=> true
680
+ Comment.count #=> 1; the comment was added to the database
681
+
682
+ result = CreateCommentCommand.new.call({ user_id: nil, body: body })
683
+
684
+ result.value #=> an instance of Comment with the given user_id and body.
685
+ result.success? #=> false
686
+ result.errors #=> ["User id can't be blank"]
687
+ Comment.count #=> 1; the comment was not added to the database
688
+ ```
689
+
653
690
  ### Results
654
691
 
655
692
  require 'cuprum'
@@ -734,6 +771,306 @@ result.halt!
734
771
  result.halted? #=> true
735
772
  ```
736
773
 
774
+ ### Command Factories
775
+
776
+ [Class Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum%2FCommandFactory)
777
+
778
+ Commands are powerful and flexible objects, but they do have a few disadvantages compared to traditional service objects which allow the developer to group together related functionality and shared implementation details. To bridge this gap, Cuprum implements the CommandFactory class. Command factories provide a DSL to quickly group together related commands and create context-specific command classes or instances.
779
+
780
+ For example, consider a basic entity command:
781
+
782
+ ```ruby
783
+ class Book
784
+ def initialize(attributes = {})
785
+ @title = attributes[:title]
786
+ @author = attributes[:author]
787
+ end
788
+
789
+ attr_accessor :author, :publisher, :title
790
+ end
791
+
792
+ class BuildBookCommand < Cuprum::Command
793
+ private
794
+
795
+ def process(attributes = {})
796
+ Book.new(attributes)
797
+ end
798
+ end
799
+
800
+ class BookFactory < Cuprum::CommandFactory
801
+ command :build, BuildBookCommand
802
+ end
803
+ ```
804
+
805
+ Our factory is defined by subclassing `Cuprum::CommandFactory`, and then we map the individual commands with the `::command` or `::command_class` class methods. In this case, we've defined a Book factory with the build command. The build command can be accessed on a factory instance in one of two ways.
806
+
807
+ First, the command class can be accessed directly as a constant on the factory instance.
808
+
809
+ ```ruby
810
+ factory = BookFactory.new
811
+ factory::Build #=> BuildBookCommand
812
+ ```
813
+
814
+ Second, the factory instance now defines a `#build` method, which returns an instance of our defined command class. This command instance can be called like any command, or returned or passed around like any other object.
815
+
816
+ ```ruby
817
+ factory = BookFactory.new
818
+
819
+ attrs = { title: 'A Wizard of Earthsea', author: 'Ursula K. Le Guin' }
820
+ command = factory.build() #=> an instance of BuildBookCommand
821
+ result = command.call(attrs) #=> an instance of Cuprum::Result
822
+ book = result.value #=> an instance of Book
823
+
824
+ book.title #=> 'A Wizard of Earthsea'
825
+ book.author #=> 'Ursula K. Le Guin'
826
+ book.publisher #=> nil
827
+ ```
828
+
829
+ #### The ::command Method And A Command Class
830
+
831
+ The first way to define a command for a factory is by calling the `::command` method and passing it the name of the command and a command class:
832
+
833
+ ```ruby
834
+ class BookFactory < Cuprum::CommandFactory
835
+ command :build, BuildBookCommand
836
+ end
837
+ ```
838
+
839
+ This makes the command class available on a factory instance as `::Build`, and generates the `#build` method which returns an instance of `BuildBookCommand`.
840
+
841
+ #### The ::command Method And A Block
842
+
843
+ By calling the `::command` method with a block, you can define a command with additional control over how the generated command. The block must return an instance of a subclass of Cuprum::Command.
844
+
845
+ ```ruby
846
+ class PublishBookCommand < Cuprum::Command
847
+ def initialize(publisher:)
848
+ @publisher = publisher
849
+ end
850
+
851
+ attr_reader :publisher
852
+
853
+ private
854
+
855
+ def process(book)
856
+ book.publisher = publisher
857
+
858
+ book
859
+ end
860
+ end
861
+
862
+ class BookFactory < Cuprum::CommandFactory
863
+ command :publish do |publisher|
864
+ PublishBookCommand.new(publisher: publisher)
865
+ end
866
+ end
867
+ ```
868
+
869
+ This defines the `#publish` method on an instance of the factory. The method takes one argument (the publisher), which is then passed on to the constructor for `PublishBookCommand` by our block. Finally, the block returns an instance of the publish command, which is then returned by `#publish`.
870
+
871
+ ```ruby
872
+ factory = BookFactory.new
873
+ book = Book.new(title: 'The Tombs of Atuan', author: 'Ursula K. Le Guin')
874
+ book.publisher #=> nil
875
+
876
+ command = factory.publish('Harper & Row') #=> an instance of PublishBookCommand
877
+ result = command.call(book) #=> an instance of Cuprum::Result
878
+ book.publisher #=> 'Harper & Row'
879
+ ```
880
+
881
+ Note that unlike when `::command` is called with a command class, calling `::command` with a block will not set a constant on the factory instance. In this case, trying to access the `PublishBookCommand` at `factory::Publish` will raise a `NameError`.
882
+
883
+ The block is evaluated in the context of the factory instance. This means that instance variables or methods are available to the block, allowing you to create commands with instance-specific configuration.
884
+
885
+ ```ruby
886
+ class PublishedBooksCommand < Cuprum::Command
887
+ def initialize(collection = [])
888
+ @collection = collection
889
+ end
890
+
891
+ attr_reader :collection
892
+
893
+ private
894
+
895
+ def process
896
+ books.reject { |book| book.publisher.nil? }
897
+ end
898
+ end
899
+
900
+ class BookFactory < Cuprum::CommandFactory
901
+ command :published do
902
+ PublishedBooksCommand.new(books_collection)
903
+ end
904
+
905
+ def initialize(books)
906
+ @books_collection = books
907
+ end
908
+
909
+ attr_reader :books_collection
910
+ end
911
+ ```
912
+
913
+ This defines the `#published` method on an instance of the factory. The method takes no arguments, but grabs the books collection from the factory instance. The block returns an instance of `PublishedBooksCommand`, which is then returned by `#published`.
914
+
915
+ ```ruby
916
+ books = [Book.new, Book.new(publisher: 'Baen'), Book.new(publisher: 'Tor')]
917
+ factory = BookFactory.new(books)
918
+ factory.books_collection #=> the books array
919
+
920
+ command = factory.published #=> an instance of PublishedBooksCommand
921
+ result = command.call #=> an instance of Cuprum::Result
922
+ ary = result.value #=> an array with the published books
923
+
924
+ ary.count #=> 2
925
+ ary.any? { |book| book.publisher == 'Baen' } #=> true
926
+ ary.any? { |book| book.publisher.nil? } #=> false
927
+ ```
928
+
929
+ Simple commands can be defined directly in the block, rather than referencing an existing command class:
930
+
931
+ ```ruby
932
+ class BookFactory < Cuprum::CommandFactory
933
+ command :published_by_baen do
934
+ Cuprum::Command.new do |books|
935
+ books.select { |book| book.publisher == 'Baen' }
936
+ end
937
+ end
938
+ end
939
+
940
+ books = [Book.new, Book.new(publisher: 'Baen'), Book.new(publisher: 'Tor')]
941
+ factory = BookFactory.new(books)
942
+
943
+ command = factory.published_by_baen #=> an instance of the anonymous command
944
+ result = command.call #=> an instance of Cuprum::Result
945
+ ary = result.value #=> an array with the selected books
946
+
947
+ ary.count #=> 1
948
+ ```
949
+
950
+ #### The ::command_class Method
951
+
952
+ The final way to define a command for a factory is calling the `::command_class` method with the command name and a block. The block must return a subclass (not an instance) of Cuprum::Command. This offers a balance between flexibility and power.
953
+
954
+ ```ruby
955
+ class SelectByAuthorCommand < Cuprum::Command
956
+ def initialize(author)
957
+ @author = author
958
+ end
959
+
960
+ attr_reader :author
961
+
962
+ private
963
+
964
+ def process(books)
965
+ books.select { |book| book.author == author }
966
+ end
967
+ end
968
+
969
+ class BooksFactory < Cuprum::CommandFactory
970
+ command_class :select_by_author do
971
+ SelectByAuthorCommand
972
+ end
973
+ end
974
+ ```
975
+
976
+ The command class can be accessed directly as a constant on the factory instance:
977
+
978
+ ```ruby
979
+ factory = BookFactory.new
980
+ factory::SelectByAuthor #=> SelectByAuthorCommand
981
+ ```
982
+
983
+ The factory instance now defines a `#select_by_author` method, which returns an instance of our defined command class. This command instance can be called like any command, or returned or passed around like any other object.
984
+
985
+ ```ruby
986
+ factory = BookFactory.new
987
+ books = [
988
+ Book.new,
989
+ Book.new(author: 'Arthur C. Clarke'),
990
+ Book.new(author: 'Ursula K. Le Guin')
991
+ ]
992
+
993
+ command = factory.select_by_author('Ursula K. Le Guin')
994
+ #=> an instance of SelectByAuthorCommand
995
+ command.author #=> 'Ursula K. Le Guin'
996
+
997
+ result = command.call(books) #=> an instance of Cuprum::Result
998
+ ary = result.value #=> an array with the selected books
999
+
1000
+ ary.count #=> 1
1001
+ ary.any? { |book| book.author == 'Ursula K. Le Guin' } #=> true
1002
+ ary.any? { |book| book.author == 'Arthur C. Clarke' } #=> false
1003
+ ary.any? { |book| book.author.nil? } #=> false
1004
+ ```
1005
+
1006
+ The block is evaluated in the context of the factory instance. This means that instance variables or methods are available to the block, allowing you to create custom command subclasses with instance-specific configuration.
1007
+
1008
+ ```ruby
1009
+ class SaveBookCommand < Cuprum::Command
1010
+ def initialize(collection = [])
1011
+ @collection = collection
1012
+ end
1013
+
1014
+ attr_reader :collection
1015
+
1016
+ private
1017
+
1018
+ def process(book)
1019
+ books << book
1020
+
1021
+ book
1022
+ end
1023
+ end
1024
+
1025
+ class BookFactory < Cuprum::CommandFactory
1026
+ command :save do
1027
+ collection = self.books_collection
1028
+
1029
+ Class.new(SaveBookCommand) do
1030
+ define_method(:initialize) do
1031
+ @books = collection
1032
+ end
1033
+ end
1034
+ end
1035
+
1036
+ def initialize(books)
1037
+ @books_collection = books
1038
+ end
1039
+
1040
+ attr_reader :books_collection
1041
+ end
1042
+ ```
1043
+
1044
+ The custom command subclass can be accessed directly as a constant on the factory instance:
1045
+
1046
+ ```ruby
1047
+ books = [Book.new, Book.new, Book.new]
1048
+ factory = BookFactory.new(books)
1049
+ factory::Save #=> a subclass of SaveBookCommand
1050
+
1051
+ command = factory::Save.new # an instance of the command subclass
1052
+ command.collection #=> the books array
1053
+ command.collection.count #=> 3
1054
+ ```
1055
+
1056
+ The factory instance now defines a `#save` method, which returns an instance of our custom command subclass. This command instance can be called like any command, or returned or passed around like any other object.
1057
+
1058
+ The custom command subclass can be accessed directly as a constant on the factory instance:
1059
+
1060
+ ```ruby
1061
+ books = [Book.new, Book.new, Book.new]
1062
+ factory = BookFactory.new(books)
1063
+ command = factory.save # an instance of the command subclass
1064
+ command.collection #=> the books array
1065
+ command.collection.count #=> 3
1066
+
1067
+ book = Book.new(title: 'The Farthest Shore', author: 'Ursula K. Le Guin')
1068
+ result = command.call(book) #=> an instance of Cuprum::Result
1069
+
1070
+ books.count #=> 4
1071
+ books.include?(book) #=> true
1072
+ ```
1073
+
737
1074
  ### Built In Commands
738
1075
 
739
1076
  Cuprum includes a small number of predefined commands and their equivalent operations.
@@ -880,7 +1217,7 @@ Generates an empty errors object. When the command is called, the result will ha
880
1217
 
881
1218
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#build_errors-instance_method)
882
1219
 
883
- #### #call
1220
+ #### `#call`
884
1221
 
885
1222
  call(*arguments, **keywords) { ... } #=> Cuprum::Result
886
1223
 
@@ -888,7 +1225,7 @@ Executes the logic encoded in the constructor block, or the #process method if n
888
1225
 
889
1226
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#call-instance_method)
890
1227
 
891
- #### #chain
1228
+ #### `#chain`
892
1229
 
893
1230
  chain(on: nil) { |result| ... } #=> Cuprum::Command
894
1231
 
@@ -904,6 +1241,18 @@ If the block returns a Cuprum::Result (or an object responding to #value and #su
904
1241
 
905
1242
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#chain-instance_method)
906
1243
 
1244
+ #### `#chain!`
1245
+
1246
+ *(Protected Method)*
1247
+
1248
+ chain!(on: nil) { |result| ... } #=> Cuprum::Command
1249
+
1250
+ chain!(command, on: nil) #=> Cuprum::Command
1251
+
1252
+ As `#chain`, but modifies the current command instead of creating a clone.
1253
+
1254
+ [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#chain!-instance_method)
1255
+
907
1256
  #### `#else`
908
1257
 
909
1258
  else(command) #=> Cuprum::Command
@@ -920,68 +1269,25 @@ If the block returns a Cuprum::Result (or an object responding to #value and #su
920
1269
 
921
1270
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#else-instance_method)
922
1271
 
923
- #### `#errors`
924
-
925
- *(Private Method)*
926
-
927
- errors() #=> Array
928
-
929
- Only available while the Command is being called. Provides access to the errors object of the generated Cuprum::Result, which is by default an instance of Array.
930
-
931
- Inside of the Command block or the `#process` method, you can add errors to the result.
932
-
933
- command =
934
- Cuprum::Command.new do
935
- errors << "I'm sorry, something went wrong."
936
-
937
- nil
938
- end # command
939
-
940
- result = command.call
941
- result.failure?
942
- #=> true
943
- result.errors
944
- #=> ["I'm sorry, something went wrong."]
945
-
946
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#errors-instance_method)
947
-
948
- #### `#failure!`
949
-
950
- failure!() #=> NilClass
951
-
952
- *(Private Method)*
953
-
954
- Only available while the Command is being called. If called, marks the result object as failing, even if the result does not have errors.
955
-
956
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#failure!-instance_method)
957
-
958
- #### `#halt!`
959
-
960
- halt!() #=> NilClass
961
-
962
- *(Private Method)*
963
-
964
- Only available while the Command is being called. If called, halts the command chain (see Chaining Commands, below). Subsequent chained commands will not be called unless they were chained with the `:on => :always` option.
965
-
966
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#halt!-instance_method)
1272
+ #### `#tap_result`
967
1273
 
968
- #### `#success!`
1274
+ tap_result(on: nil) { |previous_result| } #=> Cuprum::Result
969
1275
 
970
- success!() #=> NilClass
1276
+ Creates a copy of the command, and then chains the block to execute after the command implementation. When #call is executed, each chained block will be yielded the previous result, and the previous result returned or yielded to the next block. The return value of the block is discarded.
971
1277
 
972
- *(Private Method)*
1278
+ If the `on` parameter is omitted, the block will be called if the last result is not halted. If the `on` parameter is set to `:success`, the block will be called if the last result is successful and not halted. If the `on` parameter is set to `:failure`, the block will be called if the last result is failing and not halted. Finally, if the `on` parameter is set to `:always`, the block will always be called, even if the last result is halted.
973
1279
 
974
- Only available while the Command is being called. If called, marks the result object as passing, even if the result has errors.
1280
+ [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#tap_result-instance_method)
975
1281
 
976
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#success!-instance_method)
1282
+ #### `#tap_result!`
977
1283
 
978
- #### `#tap_result`
1284
+ *(Protected Method)*
979
1285
 
980
- tap_result(on: nil) { |previous_result| } #=> Cuprum::Result
1286
+ tap_result!(on: nil) { |previous_result| } #=> Cuprum::Result
981
1287
 
982
- Creates a copy of the command, and then chains the block to execute after the command implementation. When #call is executed, each chained block will be yielded the previous result, and the previous result returned or yielded to the next block. The return value of the block is discarded.
1288
+ As `#tap_result`, but modifies the current command instead of creating a clone.
983
1289
 
984
- If the `on` parameter is omitted, the block will be called if the last result is not halted. If the `on` parameter is set to `:success`, the block will be called if the last result is successful and not halted. If the `on` parameter is set to `:failure`, the block will be called if the last result is failing and not halted. Finally, if the `on` parameter is set to `:always`, the block will always be called, even if the last result is halted.
1290
+ [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#tap_result!-instance_method)
985
1291
 
986
1292
  #### `#then`
987
1293
 
@@ -1009,6 +1315,16 @@ If the `on` parameter is omitted, the block will be called if the last result is
1009
1315
 
1010
1316
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#yield_result-instance_method)
1011
1317
 
1318
+ #### `#yield_result!`
1319
+
1320
+ *(Protected Method)*
1321
+
1322
+ yield_result!(on: nil) { |previous_result| } #=> Cuprum::Result
1323
+
1324
+ As `#yield_result`, but modifies the current command instead of creating a clone.
1325
+
1326
+ [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#yield_result!-instance_method)
1327
+
1012
1328
  ### Cuprum::Operation
1013
1329
 
1014
1330
  require 'cuprum'