coactive 0.1.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 +7 -0
- data/.github/workflows/ci.yml +42 -0
- data/.gitignore +8 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +244 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/coactive.gemspec +27 -0
- data/gemfiles/rails50.gemfile +6 -0
- data/gemfiles/rails51.gemfile +6 -0
- data/gemfiles/rails52.gemfile +6 -0
- data/gemfiles/rails60.gemfile +5 -0
- data/gemfiles/rails61.gemfile +5 -0
- data/lib/coactive/base.rb +20 -0
- data/lib/coactive/coact.rb +33 -0
- data/lib/coactive/coaction.rb +26 -0
- data/lib/coactive/coactors.rb +34 -0
- data/lib/coactive/config.rb +28 -0
- data/lib/coactive/configure.rb +21 -0
- data/lib/coactive/loader.rb +20 -0
- data/lib/coactive/lookup.rb +35 -0
- data/lib/coactive/lookups/base.rb +20 -0
- data/lib/coactive/lookups/name.rb +30 -0
- data/lib/coactive/lookups/object.rb +45 -0
- data/lib/coactive/version.rb +5 -0
- data/lib/coactive.rb +4 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: caf295bc360ec4f4551be981b1233660a33406714b2627d1d7c3118cfde42ba1
|
4
|
+
data.tar.gz: 55a5254e390a82bf22188fb8d84253d2382e52360abc2a36a007ef129b74572f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 477b7ff382d1697943a0898ac2d8703aaa98fde5088e1f88c6e6a05f7cdee08d4071914d5a8308103ec0dd7a553df777a5d0382bf088db44bdf0d2e5f80c9b7c
|
7
|
+
data.tar.gz: 6c038fdee9aed452ac716abd2d6f29149164c57e0db32777fde17bad46652f25ba1ad34c86cad1139e90c8e41911cdae46428df9572e9b80efb783afafe815a1
|
@@ -0,0 +1,42 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
runs-on: ubuntu-18.04
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby: [2.3, 2.4, 2.5, 2.6, 2.7, 3.0]
|
12
|
+
gemfile: ['rails50', 'rails51', 'rails52', 'rails60', 'rails61']
|
13
|
+
exclude:
|
14
|
+
- ruby: 2.3
|
15
|
+
gemfile: rails60
|
16
|
+
- ruby: 2.3
|
17
|
+
gemfile: rails61
|
18
|
+
- ruby: 2.4
|
19
|
+
gemfile: rails60
|
20
|
+
- ruby: 2.4
|
21
|
+
gemfile: rails61
|
22
|
+
- ruby: 3.0
|
23
|
+
gemfile: rails50
|
24
|
+
- ruby: 3.0
|
25
|
+
gemfile: rails51
|
26
|
+
- ruby: 3.0
|
27
|
+
gemfile: rails52
|
28
|
+
|
29
|
+
name: ruby ${{ matrix.ruby }}, ${{ matrix.gemfile }}
|
30
|
+
|
31
|
+
env:
|
32
|
+
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
|
33
|
+
|
34
|
+
steps:
|
35
|
+
- uses: actions/checkout@v2
|
36
|
+
- uses: ruby/setup-ruby@v1
|
37
|
+
with:
|
38
|
+
ruby-version: ${{ matrix.ruby }}
|
39
|
+
bundler-cache: true
|
40
|
+
- name: Run test
|
41
|
+
run: |
|
42
|
+
DEBUG=1 bundle exec rspec
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Yoshikazu Kaneta
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
# Coactive
|
2
|
+
|
3
|
+
Make classes coactive.
|
4
|
+
|
5
|
+
## Dependencies
|
6
|
+
|
7
|
+
* ruby 2.3+
|
8
|
+
* activesupport 5.0+
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'coactive'
|
16
|
+
```
|
17
|
+
|
18
|
+
Then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Include `Coactive::Base` to your base class:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
class Base
|
28
|
+
include Coactive::Base
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
Define coactive classes that inherit your base class:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
class A < Base
|
36
|
+
end
|
37
|
+
|
38
|
+
class B < Base
|
39
|
+
end
|
40
|
+
|
41
|
+
class C < Base
|
42
|
+
coact A
|
43
|
+
coact B
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
You can lookup coactors as follows:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
C.new.coactors
|
51
|
+
# => [A, B]
|
52
|
+
```
|
53
|
+
|
54
|
+
### Named coactors
|
55
|
+
|
56
|
+
You can also define coactive classes by using specific name:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
class A < Base
|
60
|
+
coaction :coactive_name
|
61
|
+
end
|
62
|
+
|
63
|
+
class B < Base
|
64
|
+
coaction :coactive_name
|
65
|
+
end
|
66
|
+
|
67
|
+
class C < Base
|
68
|
+
coact :coactive_name
|
69
|
+
end
|
70
|
+
|
71
|
+
C.new.coactors
|
72
|
+
# => [A, B]
|
73
|
+
```
|
74
|
+
|
75
|
+
Coactors are looked up from descendants of your base class.
|
76
|
+
Note that the coactors are unordered.
|
77
|
+
|
78
|
+
In development mode of rails, it is necessary to load source files for looking up classes having specific coaction.
|
79
|
+
You can configure source file locations by `load_paths` as the following example:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
class Base
|
83
|
+
include Coactive::Base
|
84
|
+
|
85
|
+
configure_coactive do |config|
|
86
|
+
config.load_paths = ['app/coactors']
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
### Object-based coactors
|
92
|
+
|
93
|
+
You can also define coactive classes by using object:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
class ModelA
|
97
|
+
end
|
98
|
+
|
99
|
+
class ModelB
|
100
|
+
end
|
101
|
+
|
102
|
+
class Base::ModelA < Base
|
103
|
+
end
|
104
|
+
|
105
|
+
class Base::ModelB < Base
|
106
|
+
end
|
107
|
+
|
108
|
+
class Base::C < Base
|
109
|
+
coact ModelA
|
110
|
+
coact ModelB
|
111
|
+
end
|
112
|
+
|
113
|
+
Base::C.new.coactors
|
114
|
+
#=> [Base::ModelA, Base::ModelB]
|
115
|
+
```
|
116
|
+
|
117
|
+
Coactors are looked up from the namespace corresponding with caller classes.
|
118
|
+
|
119
|
+
You can also looked up coactors corresponding with superclass of object.
|
120
|
+
You can configure this feature by `lookup_superclass_for_object` and `lookup_superclass_until`:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
class Base
|
124
|
+
include Coactive::Base
|
125
|
+
|
126
|
+
configure_coactive do |config|
|
127
|
+
config.lookup_superclass_for_object = true
|
128
|
+
config.lookup_superclass_until = ['ActiveRecord::Base', 'ActiveModel::Base']
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
### Dynamic coactors
|
134
|
+
|
135
|
+
You can also dynamically lookup coactors by using block or instance method:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
class A < Base
|
139
|
+
end
|
140
|
+
|
141
|
+
class B < Base
|
142
|
+
end
|
143
|
+
|
144
|
+
class C < Base
|
145
|
+
# use block
|
146
|
+
coact do
|
147
|
+
if @condition == 'A'
|
148
|
+
A
|
149
|
+
else
|
150
|
+
B
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def initialize(condition)
|
155
|
+
@condition = condition
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
C.new('A').coactors
|
160
|
+
#=> [A]
|
161
|
+
C.new('B').coactors
|
162
|
+
#=> [B]
|
163
|
+
|
164
|
+
class D < Base
|
165
|
+
# use method
|
166
|
+
coact :coactivate_with_condition
|
167
|
+
|
168
|
+
def initialize(condition)
|
169
|
+
@condition = condition
|
170
|
+
end
|
171
|
+
|
172
|
+
def coactivate_with_condition
|
173
|
+
if @condition == 'A'
|
174
|
+
A
|
175
|
+
else
|
176
|
+
B
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
D.new('A').coactors
|
182
|
+
#=> [A]
|
183
|
+
D.new('B').coactors
|
184
|
+
#=> [B]
|
185
|
+
```
|
186
|
+
|
187
|
+
### Nested coactors
|
188
|
+
|
189
|
+
You can define nested coactors. For example:
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
class NestedA < Base
|
193
|
+
end
|
194
|
+
|
195
|
+
class NestedB < Base
|
196
|
+
end
|
197
|
+
|
198
|
+
class A < Base
|
199
|
+
coact NestedA
|
200
|
+
end
|
201
|
+
|
202
|
+
class B < Base
|
203
|
+
coact NestedB
|
204
|
+
end
|
205
|
+
|
206
|
+
class C < Base
|
207
|
+
coact A
|
208
|
+
coact B
|
209
|
+
end
|
210
|
+
|
211
|
+
C.new.coactors.map { |klass| [klass] + klass.new.coactors }.flatten
|
212
|
+
#=> [A, NestedA, B, NestedB]
|
213
|
+
```
|
214
|
+
|
215
|
+
### Configuration
|
216
|
+
|
217
|
+
You can set configurations in your base class as follows:
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
class Base
|
221
|
+
include Coactive::Base
|
222
|
+
|
223
|
+
configure_coactive do |config|
|
224
|
+
# path to source files for coactors
|
225
|
+
config.load_paths = ['app/coactors']
|
226
|
+
# suffix of class that inherits base class
|
227
|
+
config.class_suffix = 'Coactor'
|
228
|
+
# cache coactors in memory
|
229
|
+
config.use_cache = true
|
230
|
+
# lookup coactors corresponding with superclass of object
|
231
|
+
config.lookup_superclass_for_object = true
|
232
|
+
# lookup coactors until superclass is not in the list
|
233
|
+
config.lookup_superclass_until = ['ActiveRecord::Base', 'ActiveModel::Base']
|
234
|
+
end
|
235
|
+
end
|
236
|
+
```
|
237
|
+
|
238
|
+
## Contributing
|
239
|
+
|
240
|
+
Bug reports and pull requests are welcome at https://github.com/kanety/coactive.
|
241
|
+
|
242
|
+
## License
|
243
|
+
|
244
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "coactive"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
# require "irb"
|
14
|
+
# IRB.start
|
data/bin/setup
ADDED
data/coactive.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'coactive/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "coactive"
|
8
|
+
spec.version = Coactive::VERSION
|
9
|
+
spec.authors = ["Yoshikazu Kaneta"]
|
10
|
+
spec.email = ["kaneta@sitebridge.co.jp"]
|
11
|
+
spec.summary = %q{Make classes coactive}
|
12
|
+
spec.description = %q{Make classes coactive}
|
13
|
+
spec.homepage = "https://github.com/kanety/coactive"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
+
spec.bindir = "exe"
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "activesupport", ">= 5.0"
|
21
|
+
|
22
|
+
spec.add_development_dependency "rails", ">= 5.0"
|
23
|
+
spec.add_development_dependency "sqlite3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec-rails"
|
26
|
+
spec.add_development_dependency "simplecov"
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'configure'
|
4
|
+
require_relative 'coact'
|
5
|
+
require_relative 'coaction'
|
6
|
+
require_relative 'coactors'
|
7
|
+
require_relative 'loader'
|
8
|
+
|
9
|
+
module Coactive
|
10
|
+
module Base
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
included do
|
14
|
+
include Configure
|
15
|
+
include Coact
|
16
|
+
include Coaction
|
17
|
+
include Coactors
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coactive
|
4
|
+
module Coact
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
class_attribute :_coactants
|
9
|
+
self._coactants = []
|
10
|
+
end
|
11
|
+
|
12
|
+
class_methods do
|
13
|
+
def coact(*coactants, **options, &block)
|
14
|
+
if block
|
15
|
+
self._coactants = _coactants + [block]
|
16
|
+
elsif options[:before]
|
17
|
+
index = self._coactants.index { |coactant| coactant == options[:before] }
|
18
|
+
self._coactants = self._coactants.insert(index, *coactants)
|
19
|
+
else
|
20
|
+
self._coactants = _coactants + coactants
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def coactants
|
25
|
+
self._coactants
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear_coactants
|
29
|
+
self._coactants = []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coactive
|
4
|
+
module Coaction
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
class_attribute :_coactions
|
9
|
+
self._coactions = []
|
10
|
+
end
|
11
|
+
|
12
|
+
class_methods do
|
13
|
+
def coaction(*coactions)
|
14
|
+
self._coactions = _coactions + coactions
|
15
|
+
end
|
16
|
+
|
17
|
+
def coactions
|
18
|
+
self._coactions
|
19
|
+
end
|
20
|
+
|
21
|
+
def clear_coactions
|
22
|
+
self._coactions = []
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lookup'
|
4
|
+
|
5
|
+
module Coactive
|
6
|
+
module Coactors
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
def coactors
|
10
|
+
self.class._coactants.map do |coactant|
|
11
|
+
if coactant.is_a?(Symbol) && respond_to?(coactant, true)
|
12
|
+
send(coactant)
|
13
|
+
elsif coactant.is_a?(Proc)
|
14
|
+
instance_exec(&coactant)
|
15
|
+
else
|
16
|
+
coactant
|
17
|
+
end
|
18
|
+
end.flatten.compact.map do |coactant|
|
19
|
+
if coactant.is_a?(Class) && coactant < self.class.coactive_config.base_class
|
20
|
+
coactant
|
21
|
+
else
|
22
|
+
self.class.coactors(coactant)
|
23
|
+
end
|
24
|
+
end.flatten.compact
|
25
|
+
end
|
26
|
+
|
27
|
+
class_methods do
|
28
|
+
def coactors(*coactants)
|
29
|
+
coactants = _coactants unless coactants
|
30
|
+
coactants.map { |coactant| Lookup.call(self, coactant) }.flatten
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coactive
|
4
|
+
class Config
|
5
|
+
DEFAULTS = {
|
6
|
+
base_class: nil,
|
7
|
+
load_paths: ['app/coactors'],
|
8
|
+
class_suffix: 'Coactor',
|
9
|
+
use_cache: true,
|
10
|
+
lookup_superclass_for_object: true,
|
11
|
+
lookup_superclass_until: ['ActiveRecord::Base', 'ActiveModel::Base'],
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@data = DEFAULTS.deep_dup
|
16
|
+
end
|
17
|
+
|
18
|
+
DEFAULTS.keys.each do |key|
|
19
|
+
define_method "#{key}" do
|
20
|
+
@data[key]
|
21
|
+
end
|
22
|
+
|
23
|
+
define_method "#{key}=" do |val|
|
24
|
+
@data[key] = val
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'config'
|
4
|
+
|
5
|
+
module Coactive
|
6
|
+
module Configure
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
class_attribute :coactive_config
|
11
|
+
self.coactive_config = Config.new
|
12
|
+
self.coactive_config.base_class = self
|
13
|
+
end
|
14
|
+
|
15
|
+
class_methods do
|
16
|
+
def configure_coactive
|
17
|
+
yield coactive_config
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coactive
|
4
|
+
module Loader
|
5
|
+
class << self
|
6
|
+
def call(paths)
|
7
|
+
return unless defined?(Rails)
|
8
|
+
return if Rails.application.config.eager_load
|
9
|
+
return if paths.blank?
|
10
|
+
|
11
|
+
engines = [Rails] + Rails::Engine.subclasses.map(&:instance)
|
12
|
+
engines.each do |engine|
|
13
|
+
Dir["#{engine.root}/{#{Array(paths).join(',')}}/**/*.rb"].each do |file|
|
14
|
+
require file
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lookups/base'
|
4
|
+
require_relative 'lookups/name'
|
5
|
+
require_relative 'lookups/object'
|
6
|
+
|
7
|
+
module Coactive
|
8
|
+
class Lookup
|
9
|
+
class << self
|
10
|
+
class_attribute :lookups
|
11
|
+
self.lookups = [Lookups::Name, Lookups::Object]
|
12
|
+
|
13
|
+
class_attribute :cache
|
14
|
+
self.cache = {}
|
15
|
+
|
16
|
+
def call(klass, coactivation)
|
17
|
+
with_cache(klass, coactivation) do
|
18
|
+
lookup = lookups.detect { |lookup| lookup.callable?(coactivation) }
|
19
|
+
lookup.new(klass, coactivation).call if lookup
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def with_cache(klass, coactivation)
|
26
|
+
if klass.coactive_config.use_cache
|
27
|
+
self.cache[klass] ||= {}
|
28
|
+
self.cache[klass][coactivation] ||= yield
|
29
|
+
else
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coactive
|
4
|
+
module Lookups
|
5
|
+
class Base
|
6
|
+
def initialize(klass, coactant)
|
7
|
+
@klass = klass
|
8
|
+
@coactant = coactant
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def callable?(coactant)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coactive
|
4
|
+
module Lookups
|
5
|
+
class Name < Base
|
6
|
+
def call
|
7
|
+
load_files
|
8
|
+
lookup
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def load_files
|
14
|
+
Coactive::Loader.call(@klass.coactive_config.load_paths)
|
15
|
+
end
|
16
|
+
|
17
|
+
def lookup
|
18
|
+
@klass.coactive_config.base_class.descendants.select do |coactor|
|
19
|
+
coactor._coactions.any? { |coaction| coaction == @coactant }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def callable?(coactant)
|
25
|
+
coactant.is_a?(Symbol)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coactive
|
4
|
+
module Lookups
|
5
|
+
class Object < Base
|
6
|
+
def call
|
7
|
+
lookup(@coactant)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def lookup(coactant)
|
13
|
+
return if terminate?(coactant)
|
14
|
+
|
15
|
+
if coactant.name.present? && (coactor = resolve(coactant))
|
16
|
+
coactor
|
17
|
+
elsif @klass.coactive_config.lookup_superclass_for_object && coactant.superclass
|
18
|
+
lookup(coactant.superclass)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def terminate?(coactant)
|
23
|
+
coactant.name.to_s.in?(@klass.coactive_config.lookup_superclass_until)
|
24
|
+
end
|
25
|
+
|
26
|
+
def resolve(coactant)
|
27
|
+
name = resolve_name(coactant)
|
28
|
+
coactor = name.safe_constantize
|
29
|
+
return coactor if coactor && name == coactor.name
|
30
|
+
end
|
31
|
+
|
32
|
+
def resolve_name(coactant)
|
33
|
+
suffix = @klass.coactive_config.class_suffix
|
34
|
+
namespace = @klass.name.to_s.sub(/#{suffix}$/, '').to_s
|
35
|
+
[namespace, "#{coactant.name}#{suffix}"].join('::')
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
def callable?(coactant)
|
40
|
+
coactant.is_a?(Module)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/coactive.rb
ADDED
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: coactive
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yoshikazu Kaneta
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-11-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Make classes coactive
|
98
|
+
email:
|
99
|
+
- kaneta@sitebridge.co.jp
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".github/workflows/ci.yml"
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rspec"
|
107
|
+
- CHANGELOG.md
|
108
|
+
- Gemfile
|
109
|
+
- LICENSE
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- bin/console
|
113
|
+
- bin/setup
|
114
|
+
- coactive.gemspec
|
115
|
+
- gemfiles/rails50.gemfile
|
116
|
+
- gemfiles/rails51.gemfile
|
117
|
+
- gemfiles/rails52.gemfile
|
118
|
+
- gemfiles/rails60.gemfile
|
119
|
+
- gemfiles/rails61.gemfile
|
120
|
+
- lib/coactive.rb
|
121
|
+
- lib/coactive/base.rb
|
122
|
+
- lib/coactive/coact.rb
|
123
|
+
- lib/coactive/coaction.rb
|
124
|
+
- lib/coactive/coactors.rb
|
125
|
+
- lib/coactive/config.rb
|
126
|
+
- lib/coactive/configure.rb
|
127
|
+
- lib/coactive/loader.rb
|
128
|
+
- lib/coactive/lookup.rb
|
129
|
+
- lib/coactive/lookups/base.rb
|
130
|
+
- lib/coactive/lookups/name.rb
|
131
|
+
- lib/coactive/lookups/object.rb
|
132
|
+
- lib/coactive/version.rb
|
133
|
+
homepage: https://github.com/kanety/coactive
|
134
|
+
licenses: []
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubygems_version: 3.1.2
|
152
|
+
signing_key:
|
153
|
+
specification_version: 4
|
154
|
+
summary: Make classes coactive
|
155
|
+
test_files: []
|