ii_interactor 1.1.1 → 1.2.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: 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: []