ii_interactor 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98e0554614d026c2bfae6957324c4865bcc5b42accda1722c597415de801b222
4
- data.tar.gz: 53cdc0666633a1ab0f04b0ed7200a3e3444ca846f7e78ba1f05106fc9bfe021b
3
+ metadata.gz: 9e2c11382c90fb3533448d1ddc3ed2f1ca922abb204570beba2eed4ad264fbef
4
+ data.tar.gz: dd2cd0bab63421c2c45b595438e2b4ef2f914abc041ce1cb1a655cd6ac98575c
5
5
  SHA512:
6
- metadata.gz: 7b82959dadcc853ad7b1123f8282a23a25704bee0c462923cd41da6de357fa64f8d929139c37a5a94d21d49c5a2750eb265af046f76bb2ef8e5383592c0b4259
7
- data.tar.gz: 790eb7bfc8de896dd22b9af3b8546721022a45c2fb3a86b3d6c6241a5aab269eb7c76c29491ee4c11a359486b7e13f858e5813f2aa639a72a03b28e233b90508
6
+ metadata.gz: e4ba848c2b8582434360c1f9f47b646fcea0e1954ec64419d8beb1b46b8bedd73876cc49de3f0a2f6258dc49db034e468b34bb90794a00c8807060cc2304ddb3
7
+ data.tar.gz: e765a8adb58f62202ca6e35e302846185d575776805aaed73bc9495de7ebd6bca800f864d47bb176da5731b012af6897272e9810efee7f22af56b3807019d7a2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.2.0
4
+
5
+ * Add variable setting feature.
6
+
3
7
  ## 1.1.1
4
8
 
5
9
  * Check `config.eager_load` instead of `Rails.env` before file loading.
data/README.md CHANGED
@@ -36,8 +36,73 @@ Interactor.call(message: 'something')
36
36
  #=> #<IIInteractor::Context message="something", result="called by something">
37
37
  ```
38
38
 
39
- The first argument of `call` is set to `@context`.
40
- The return value of `call` is the same as `@context`.
39
+ The first argument of `Interactor.call` is set to `@context`.
40
+ The return value of `Interactor.call` is the same as `@context`.
41
+
42
+ ### Context variables
43
+
44
+ You can define context variables used in interactor explicitly.
45
+ For example:
46
+
47
+ ```ruby
48
+ class Interactor < IIInteractor::Base
49
+ context_in :input
50
+ context_out :result
51
+
52
+ def call
53
+ puts @input
54
+ @result = 'result value'
55
+ end
56
+ end
57
+
58
+ puts Interactor.call(input: 'input').result
59
+ #=> input
60
+ # result value
61
+ ```
62
+
63
+ `context_in` copies context into instance variables of interactor,
64
+ while `context_out` copies instance variables of interactor into context.
65
+
66
+ You can also define required context as follows:
67
+
68
+ ```ruby
69
+ class Interactor < IIInteractor::Base
70
+ context_in :input, required: true
71
+ end
72
+
73
+ Interactor.call
74
+ #=> IIInteractor::RequiredContextError (missing required context: input2)
75
+ ```
76
+
77
+ You can also define default value as follows:
78
+
79
+ ```ruby
80
+ class Interactor < IIInteractor::Base
81
+ context_in :input, default: 'input'
82
+
83
+ def call
84
+ puts @input
85
+ end
86
+ end
87
+
88
+ Interactor.call
89
+ #=> input
90
+ ```
91
+
92
+ You can also set context from return value of `call` method:
93
+
94
+ ```ruby
95
+ class Interactor < IIInteractor::Base
96
+ context_out :result, from_return: true
97
+
98
+ def call
99
+ 'returned value'
100
+ end
101
+ end
102
+
103
+ Interactor.call.result
104
+ #=> returned value
105
+ ```
41
106
 
42
107
  ### Callbacks
43
108
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'context'
4
4
  require_relative 'core'
5
+ require_relative 'variables'
5
6
  require_relative 'callbacks'
6
7
  require_relative 'instrumentation'
7
8
  require_relative 'interaction'
@@ -12,6 +13,7 @@ module IIInteractor
12
13
  include Core
13
14
  include Callbacks
14
15
  include Instrumentation
16
+ include Variables
15
17
  include Interaction
16
18
  include Lookup
17
19
  end
@@ -7,7 +7,6 @@ module IIInteractor
7
7
  self[:_block] = block
8
8
  self[:_failed] = false
9
9
  self[:_stopped] = false
10
- self[:_planned] = []
11
10
  self[:_called] = []
12
11
  end
13
12
 
@@ -18,7 +18,6 @@ module IIInteractor
18
18
 
19
19
  def call_all
20
20
  planned = lookup.map { |interactor| interactor.new(@context) } + [self]
21
- @context._planned += planned
22
21
  planned.each_with_index do |interactor, i|
23
22
  if i == planned.size - 1
24
23
  interactor.call_self
@@ -30,8 +29,9 @@ module IIInteractor
30
29
  end
31
30
 
32
31
  def call_self
33
- call
34
- @context._called << self
32
+ call.tap do
33
+ @context._called << self
34
+ end
35
35
  end
36
36
 
37
37
  def call
@@ -54,8 +54,8 @@ module IIInteractor
54
54
  end
55
55
 
56
56
  class_methods do
57
- def call(context = {}, &block)
58
- interactor = new(context, &block)
57
+ def call(*args, &block)
58
+ interactor = new(*args, &block)
59
59
  interactor.call_all
60
60
  interactor.context
61
61
  rescue UnprogressableError
@@ -3,4 +3,7 @@
3
3
  module IIInteractor
4
4
  class UnprogressableError < StandardError
5
5
  end
6
+
7
+ class RequiredContextError < StandardError
8
+ end
6
9
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IIInteractor
4
+ class Variable < Struct.new(:name, :options)
5
+ def default
6
+ options[:default] if options
7
+ end
8
+
9
+ def required?
10
+ options[:required] if options
11
+ end
12
+
13
+ def from_return?
14
+ options[:from_return] if options
15
+ end
16
+ end
17
+
18
+ module Variables
19
+ extend ActiveSupport::Concern
20
+
21
+ def call_self
22
+ (self.class.context_ins + self.class.context_outs).each do |var|
23
+ if var.required? && !@context.respond_to?(var.name)
24
+ raise RequiredContextError.new("missing required context: #{var.name}")
25
+ end
26
+ if var.default && !@context.respond_to?(var.name)
27
+ @context[var.name] = Variables.resolve(self, var.default)
28
+ end
29
+ instance_variable_set("@#{var.name}", @context[var.name])
30
+ end
31
+
32
+ super.tap do |return_value|
33
+ self.class.context_outs.each do |var|
34
+ @context[var.name] =
35
+ if var.from_return?
36
+ return_value
37
+ else
38
+ instance_variable_get("@#{var.name}")
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ class << self
45
+ def resolve(interactor, value)
46
+ if value.respond_to?(:call)
47
+ interactor.instance_exec(&value)
48
+ elsif value.is_a?(Symbol) && interactor.respond_to?(value, true)
49
+ interactor.send(value)
50
+ else
51
+ value.deep_dup
52
+ end
53
+ end
54
+ end
55
+
56
+ included do
57
+ class_attribute :context_ins, :context_outs
58
+ self.context_ins = []
59
+ self.context_outs = []
60
+ end
61
+
62
+ class_methods do
63
+ def context_in(*names, **options)
64
+ self.context_ins = self.context_ins + names.map { |name| Variable.new(name, options) }
65
+ end
66
+
67
+ def context_out(*names, **options)
68
+ self.context_outs = self.context_outs + names.map { |name| Variable.new(name, options) }
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IIInteractor
4
- VERSION = '1.1.1'
4
+ VERSION = '1.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ii_interactor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshikazu Kaneta
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-24 00:00:00.000000000 Z
11
+ date: 2021-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -132,6 +132,7 @@ files:
132
132
  - lib/ii_interactor/lookups/base.rb
133
133
  - lib/ii_interactor/lookups/name.rb
134
134
  - lib/ii_interactor/lookups/object.rb
135
+ - lib/ii_interactor/variables.rb
135
136
  - lib/ii_interactor/version.rb
136
137
  homepage: https://github.com/kanety/ii_interactor
137
138
  licenses: []