Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kanety/coactive
https://github.com/kanety/coactive
Last synced: 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/kanety/coactive
- Owner: kanety
- License: mit
- Created: 2021-11-14T10:43:48.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2024-10-21T00:43:06.000Z (3 months ago)
- Last Synced: 2024-10-21T04:07:15.909Z (3 months ago)
- Language: Ruby
- Size: 52.7 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Coactive
Make classes coactive.
## Dependencies
* ruby 2.3+
* activesupport 5.0+## Installation
Add this line to your application's Gemfile:
```ruby
gem 'coactive'
```Then execute:
$ bundle
## Usage
### Coactors
Include `Coactive::Base` to your base class:
```ruby
class Base
include Coactive::Base
end
```Define coactive classes that inherit your base class:
```ruby
class A < Base
endclass B < Base
endclass C < Base
coact A
coact B
end
```You can lookup coactors as follows:
```ruby
C.new.coactors
# => [A, B]
```#### Named coactors
You can also define coactive classes by using specific name:
```ruby
class A < Base
coaction :coactive_name
endclass B < Base
coaction :coactive_name
endclass C < Base
coact :coactive_name
endC.new.coactors
# => [A, B]
```Coactors are looked up from descendants of your base class.
Note that the coactors are unordered.In development mode of rails, it is necessary to load source files for looking up classes having specific coaction.
You can configure source file locations by `load_paths` as the following example:```ruby
class Base
include Coactive::Baseconfigure_coactive do |config|
config.load_paths = ['app/coactors']
end
end
```#### Object-based coactors
You can also define coactive classes by using object:
```ruby
class ItemA
endclass ItemB
endclass Base::ItemA < Base
endclass Base::ItemB < Base
endclass Base::C < Base
coact ItemA
coact ItemB
endBase::C.new.coactors
#=> [Base::ItemA, Base::ItemB]
```Coactors are looked up from the namespace corresponding with caller classes.
You can also looked up coactors corresponding with superclass of object.
You can configure this feature by `lookup_superclass_for_object` and `lookup_superclass_until`:```ruby
class Base
include Coactive::Baseconfigure_coactive do |config|
config.lookup_superclass_for_object = true
config.lookup_superclass_until = ['ActiveRecord::Base', 'ActiveModel::Base']
end
end
```#### Dynamic coactors
You can also dynamically lookup coactors by using block or instance method:
```ruby
class A < Base
endclass B < Base
endclass C < Base
# use block
coact do
if @condition == 'A'
A
else
B
end
enddef initialize(condition)
@condition = condition
end
endC.new('A').coactors
#=> [A]
C.new('B').coactors
#=> [B]class D < Base
# use method
coact :coactivate_with_conditiondef initialize(condition)
@condition = condition
enddef coactivate_with_condition
if @condition == 'A'
A
else
B
end
end
endD.new('A').coactors
#=> [A]
D.new('B').coactors
#=> [B]
```#### Nested coactors
You can define nested coactors. For example:
```ruby
class NestedA < Base
endclass NestedB < Base
endclass A < Base
coact NestedA
endclass B < Base
coact NestedB
endclass C < Base
coact A
coact B
endC.new.coactors.map { |klass| [klass] + klass.new.coactors }.flatten
#=> [A, NestedA, B, NestedB]
```### Context
You can define variables used in a coactor as a context by including `Coactive::Initializer`.
The variables are stored in `context` as follows:```ruby
class Base
include Coactive::Base
include Coactive::Initializer
endclass A < Base
context :input
endcoactor = A.new(input: 'something')
coactor.context.input
#=> something
```#### Required context
You can also define required context as follows:
```ruby
class A < Base
context :input, required: true
endA.new
#=> Coactive::MissingContextError (missing required context: input)
```#### Default value
You can also define default value as follows:
```ruby
class A < Base
context :input, default: 'something'
endcoactor = A.new
coactor.context.input
#=> something
```### Contextualizer
You can copy context variables to a coactor by calling `contextualize`:
```ruby
class Base
include Coactive::Base
include Coactive::Initializer
include Coactive::Contextualizer
endclass A < Base
context :input
endcoactor = A.new(input: 'something')
coactor.contextualize
coactor.input
#=> something
coactor.instance_variable_get(:@input)
#=> something
```#### Output
You can also set context when finished `contextualize` block:
```ruby
class A < Base
context :result, output: truedef call
@result = 'something'
end
endcoactor = A.new
coactor.contextualize { coactor.call }
coactor.context.result
#=> something
```#### Output return value
You can also set context from return value of `contextualize` block:
```ruby
class A < Base
context :result, output: :return
endcoactor = A.new
coactor.contextualize { 'return value' }
coactor.context.result
#=> return value
```### Configuration
You can set configurations in your base class as follows:
```ruby
class Base
include Coactive::Baseconfigure_coactive do |config|
# path to source files for coactors
config.load_paths = ['app/coactors']
# suffix of class that inherits base class
config.class_suffix = 'Coactor'
# cache coactors in memory
config.use_cache = true
# lookup coactors corresponding with superclass of object
config.lookup_superclass_for_object = true
# lookup coactors until superclass is not in the list
config.lookup_superclass_until = ['ActiveRecord::Base', 'ActiveModel::Base']
end
end
```## Contributing
Bug reports and pull requests are welcome at https://github.com/kanety/coactive.
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).