service_actor 3.8.1 → 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: ca3921af29250e8b2b68925ede79f0ad223d87bfa1be362e8e50cc178999658f
4
- data.tar.gz: 86f770c478e718d0c1c20f0809ade458d1687cabeac24b35cfa39d35430ea35d
3
+ metadata.gz: 240bbafeef337eec8bdb7f265b1c5ad1715ae4909967e65eb0fb313d3aaa74e8
4
+ data.tar.gz: 7b8a442ff7ffec97bc9cd1466f5c6a2074e10bfa7edf6319468138acb37ad0d0
5
5
  SHA512:
6
- metadata.gz: 29cfec59fba54ea9ea8ddd4a250588513ad3132d5ecef79f6d6f43a58c5fa6aded756bc34cd6e698f233e4d584072f7f7e7342e8e3ee71cb1027463334450c7b
7
- data.tar.gz: 73b264aa00a02f23513da5b3b61b5a4a2b9a5afc72bb627d929f0a27c44a5cebf01b561d7e62c17fdb5293886f1bf65a6af0b69d0bd68674c2cad19eaef92ab3
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)
@@ -33,7 +33,7 @@ class ServiceActor::Result < BasicObject
33
33
  end
34
34
 
35
35
  def to_h
36
- data
36
+ filter_default_output(data)
37
37
  end
38
38
 
39
39
  def inspect
@@ -59,7 +59,7 @@ class ServiceActor::Result < BasicObject
59
59
  end
60
60
 
61
61
  def failure?
62
- data[:failure] || false
62
+ data[:failure] || data[:failure?] || false
63
63
  end
64
64
 
65
65
  def error
@@ -103,6 +103,14 @@ class ServiceActor::Result < BasicObject
103
103
 
104
104
  attr_reader :data
105
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
+
106
114
  def respond_to_missing?(method_name, _include_private = false)
107
115
  return true if method_name.end_with?("=")
108
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.1"
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.1
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-26 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
@@ -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: