service_actor 3.8.0 → 3.9.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
  SHA256:
3
- metadata.gz: a852443e88e3b6957cbaf093330d08691ba8e862826ac3b745fa5510d1b0273c
4
- data.tar.gz: 21a7648a3e3302600b1946285a76b0e80c70ba1550776dfd07057718397d5f66
3
+ metadata.gz: 240bbafeef337eec8bdb7f265b1c5ad1715ae4909967e65eb0fb313d3aaa74e8
4
+ data.tar.gz: 7b8a442ff7ffec97bc9cd1466f5c6a2074e10bfa7edf6319468138acb37ad0d0
5
5
  SHA512:
6
- metadata.gz: 692cc4e5240be00b9a184daf7e7ec921976649ec98c991e14b538e6be37e61462d06dadaa72704010f59c2f3c61ce5921a64871e5050e5fc0efb9a8a118c94d8
7
- data.tar.gz: bc2a009e14baaa36d81179fd38f77ed22a972cc9486b0f5d511f4c49bef865d4e940fc990745a07922687340be4999f956f50bd4faae78c1567cb17d7902fd05
6
+ metadata.gz: b8491915f458d3dae52063f3d4f2131c246101dd50393a9de921d7e68e6189f0eddbc87910438bd8f9a9a68f36f72a5b50c121c4879f07053ad1f0e2ec61be16
7
+ data.tar.gz: 4be5e6db8633232e0af626c0c71cb978c78b05be9082058f7bad3aeb81fa485975ade749f8be830f26ac049dc543c78553e0d0182e7d066e1c6e535bb2760fc2
data/README.md CHANGED
@@ -123,6 +123,22 @@ actor.greeting # => "Have a wonderful day!"
123
123
  actor.greeting? # => true
124
124
  ```
125
125
 
126
+ If you only have one value you want from an actor, you can skip defining an
127
+ output by making it the return value of `.call()` and calling your actor with
128
+ `.value()`:
129
+
130
+ ```rb
131
+ class BuildGreeting < Actor
132
+ input :name
133
+
134
+ def call
135
+ "Have a wonderful day, #{name}!"
136
+ end
137
+ end
138
+
139
+ BuildGreeting.value(name: "Fred") # => "Have a wonderful day, Fred!"
140
+ ```
141
+
126
142
  ### Fail
127
143
 
128
144
  To stop the execution and mark an actor as having failed, use `fail!`:
@@ -183,6 +199,9 @@ Calling this actor will now call every actor along the way. Inputs and outputs
183
199
  will go from one actor to the next, all sharing the same result set until it is
184
200
  finally returned.
185
201
 
202
+ If you use `.value()` to call this actor, it will give the return value of
203
+ the final actor in the play chain.
204
+
186
205
  ### Rollback
187
206
 
188
207
  When using `play`, if an actor calls `fail!`, the following actors will not be
@@ -15,6 +15,7 @@ module ServiceActor::Base
15
15
  base.include(ServiceActor::Checkable)
16
16
  base.include(ServiceActor::Defaultable)
17
17
  base.include(ServiceActor::Failable)
18
+ base.include(ServiceActor::Valuable)
18
19
  end
19
20
  end
20
21
  end
@@ -20,8 +20,9 @@ module ServiceActor::Checkable
20
20
  self.service_actor_argument_errors = []
21
21
 
22
22
  service_actor_checks_for(:input)
23
- super
23
+ return_val = super
24
24
  service_actor_checks_for(:output)
25
+ return_val
25
26
  end
26
27
 
27
28
  private
@@ -45,6 +45,8 @@ module ServiceActor::Core
45
45
  # This method is used internally to override behavior on call. Overriding
46
46
  # `call` instead would mean that end-users have to call `super` in their
47
47
  # actors.
48
+ # When overriding and calling `super`, make sure the final value is the return
49
+ # value of `super` (see e.g. ServiceActor::Checkable).
48
50
  # :nodoc:
49
51
  def _call
50
52
  call
@@ -54,11 +54,17 @@ module ServiceActor::Playable
54
54
 
55
55
  module PrependedMethods
56
56
  def call
57
+ default_output = nil
58
+
57
59
  self.class.play_actors.each do |options|
58
60
  next unless callable_actor?(options)
59
61
 
60
- options[:actors].each { |actor| play_actor(actor) }
62
+ options[:actors].each do |actor|
63
+ default_output = play_actor(actor)
64
+ end
61
65
  end
66
+
67
+ default_output
62
68
  rescue self.class.failure_class
63
69
  rollback
64
70
  raise
@@ -95,17 +101,18 @@ module ServiceActor::Playable
95
101
  return unless actor.ancestors.include?(ServiceActor::Core)
96
102
 
97
103
  actor = actor.new(result)
98
- actor._call
104
+ call_output = actor._call
99
105
 
100
106
  (@played_actors ||= []).unshift(actor)
107
+
108
+ call_output
101
109
  end
102
110
 
103
111
  def play_method(actor)
104
112
  return unless actor.is_a?(Symbol)
105
113
 
106
- send(actor)
107
-
108
- true
114
+ # return truthy method value, or true as fallback
115
+ send(actor) || true
109
116
  end
110
117
 
111
118
  def play_interactor(actor)
@@ -11,7 +11,18 @@ class ServiceActor::Result < BasicObject
11
11
  end
12
12
  end
13
13
 
14
- %i[class is_a? kind_of? send tap then block_given?].each do |method_name|
14
+ %i[
15
+ class
16
+ is_a?
17
+ kind_of?
18
+ send
19
+ public_send
20
+ tap
21
+ then
22
+ block_given?
23
+ object_id
24
+ instance_variables
25
+ ].each do |method_name|
15
26
  define_method(method_name, ::Kernel.instance_method(method_name))
16
27
  end
17
28
 
@@ -22,7 +33,7 @@ class ServiceActor::Result < BasicObject
22
33
  end
23
34
 
24
35
  def to_h
25
- data
36
+ filter_default_output(data)
26
37
  end
27
38
 
28
39
  def inspect
@@ -48,7 +59,11 @@ class ServiceActor::Result < BasicObject
48
59
  end
49
60
 
50
61
  def failure?
51
- data[:failure] || false
62
+ data[:failure] || data[:failure?] || false
63
+ end
64
+
65
+ def error
66
+ data[:error] || nil
52
67
  end
53
68
 
54
69
  def merge!(result)
@@ -88,6 +103,14 @@ class ServiceActor::Result < BasicObject
88
103
 
89
104
  attr_reader :data
90
105
 
106
+ # Key `_default_output` is an internal datum used by actor class
107
+ # method `.valuable`. Don't expose it with the rest of the result.
108
+ def filter_default_output(h)
109
+ # using `filter` instead of `except` to maintain Ruby 2.7 compatibility
110
+ # update once support for 2.7 is dropped
111
+ h.filter { |k| k != :_default_output }
112
+ end
113
+
91
114
  def respond_to_missing?(method_name, _include_private = false)
92
115
  return true if method_name.end_with?("=")
93
116
  if method_name.end_with?("?") &&
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Adds the `value` method to actors. This allows you to call `.value` and get
4
+ # back the return value of that actor's `call` method.
5
+ #
6
+ # In the case of play actors, it will return the value of the final actor's
7
+ # `call` method in the chain.
8
+ #
9
+ # class MyActor < Actor
10
+ # def call
11
+ # "foo"
12
+ # end
13
+ # end
14
+ #
15
+ # > MyActor.value
16
+ # => "foo"
17
+ module ServiceActor::Valuable
18
+ class << self
19
+ def included(base)
20
+ base.extend(ClassMethods)
21
+ base.prepend(PrependedMethods)
22
+ end
23
+ end
24
+
25
+ module ClassMethods
26
+ def value(result = nil, **arguments)
27
+ call(result, **arguments)[:_default_output]
28
+ end
29
+ end
30
+
31
+ module PrependedMethods
32
+ def _call
33
+ result[:_default_output] = super
34
+ end
35
+ end
36
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ServiceActor
4
- VERSION = "3.8.0"
4
+ VERSION = "3.9.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: service_actor
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.8.0
4
+ version: 3.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sunny Ripert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-21 00:00:00.000000000 Z
11
+ date: 2024-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -81,19 +81,19 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '18.2'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rspec-block_is_expected
84
+ name: standard-rubocop-lts
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '1.0'
89
+ version: 1.0.10
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '1.0'
96
+ version: 1.0.10
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop-gradual
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -223,6 +223,7 @@ files:
223
223
  - lib/service_actor/playable.rb
224
224
  - lib/service_actor/result.rb
225
225
  - lib/service_actor/support/loader.rb
226
+ - lib/service_actor/valuable.rb
226
227
  - lib/service_actor/version.rb
227
228
  homepage: https://github.com/sunny/actor
228
229
  licenses: