Basic configuration is relatively simple but tedious to do if done multiple times. throughout a project. The intention of ClassComposer
is to DRY up as much of that configuration as possible to allow you to just write code.
ClassComposer
is hosted on RubyGems https://rubygems.org/gems/class_composer
Add this line to your application's Gemfile:
gem 'class_composer'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install class_composer
add_composer
is the driving method behind the composer gem. It will
- Add a setter Method
- Add a getter Method
- Add instance variable
- Add validation Method
In short, Composer will behave similarly to attr_accessor
require 'class_composer'
class MyConfigurableClass
include ClassComposer::Generator
ALLOWED_FIBONACCI = [0, 2, 8, 13, 34]
add_composer :status, allowed: Integer, default: 35
add_composer :number, allowed: Integer, default: 0, validator: -> (val) { val < 50 }
# when no default is provided, nil will be returned
add_composer :fibbonacci, allowed: Array, validator: ->(val) { val.all? {|i| i.is_a?(Integer) } && val.all? { |i| ALLOWED_FIBONACCI.include?(i) } }, invalid_message: ->(val) { "We only allow #{ALLOWED_FIBONACCI} numbers. Received #{val}" }
# Allowed can be passed an array of allowed class types
add_composer :type, allowed: [Proc, Integer], default: 35
end
instance = MyConfigurableClass.new
instance.type
=> 35
instance.number = 75
ClassComposer::ValidatorError: MyConfigurableClass.number failed validation. number is expected to be Integer.
from /gem/lib/class_composer/generator.rb:71:in `block in __composer_assignment__`
instance.number = 15
=> 15
instance.number
=> 15
instance.fibbonacci
=> nil
instance.fibbonacci = [1,2,3]
ClassComposer::ValidatorError: MyConfigurableClass.fibbonacci failed validation. fibbonacci is expected to be [Array]. We only allow [0, 2, 8, 13, 34] numbers. Received [1, 2, 3]
from /gem/lib/class_composer/generator.rb:71:in `block in __composer_assignment__`
instance.fibbonacci = [0,13,34]
=> [0, 13, 34]
instance.fibbonacci
=> [0, 13, 34]
allowed
- Required: True
- What: Expected value of the name of the composed method
- Type: Array of Class types or Single Class type
validator
- Required: False
- What: Custom way to validate the value of the composed method
- Type: Proc
- Default: ->(_) { true }
- By default validation happens on the `allowed` KWARG first and then the passed in validator function. Proc should expect that the type passed in is one of `allowed`
validation_error_klass
- Required: false
- What: Class to raise when a validation error occurs from `allowed` KWarg or from the passed in `validator` proc
- Type: Class
- Default: ClassComposer::ValidatorError
validation_error_klass
- Required: false
- What: Class to raise when a errors occur outside of validation. This can be for composer method errors or proc errors during validation
- Type: Class
- Default: ClassComposer::Error
default
- Required: false
- What: This is the default value to set for the composed method
- Type: Should match the `allowed` KWarg
- Default: nil
- Note: When no default value is provided, the return value from the getter will be `nil`. However, this does not mean that NilClass will be an acceptable value during the setter method
invalid_message
- Required: False
- What: Message to add to the base invalid setter method
- Type: Proc or String
- Proc: ->(val) { } # where val is the failed value of the setter method
Arrays are treated special with the composed methods. ClassComposer
will inject a custom method <<
so that it can be treated as a regular array with the added benefit of validation still occuring.
class CustomArrayClass
include ClassComposer::Generator
add_composer :array, allowed: Array, default: [], validator: ->(val) { val.sum < 40 }, invalid_message: ->(val) { "Array sum of [#{val.sum}] must be less than 40" }
end
instance = CustomArrayClass.new
instance.array << 1
instance.array << 2
instance.array
=> [1, 2]
instance.array << 50
ClassComposer::ValidatorError: CustomArrayClass.array failed validation. array is expected to be Array. Array sum of [53] must be less than 40
class ComplexDependencies
include ClassComposer::Generator
add_composer :use_scope, allowed: [TrueClass, FalseClass], default: false
add_composer :scope, allowed: Proc
def scope
# skip unless use_scope is explicitly set
return -> {} unless @use_scope
# use passed in scope if present
# Otherwise default to blank default
@scope || -> {}
end
end
Adding custom methods allows for higher level of complexity. The methods can be used and accessed just as an attr_accessor
would.
After checking out the repo, run bin/setup
to install dependencies. Then, run
rake rspec
to run the tests. You can also run bin/console
for an interactive
prompt that will allow you to experiment. Run bundle exec class_composer
to use
the gem in this directory, ignoring other installed copies of this gem.
To install this gem onto your local machine, run bundle exec rake install
.
To release a new version:
- Update the version number in [lib/class_composer/version.rb]
- Update [CHANGELOG.md]
- Merge to the main branch. This will trigger an automatic build in CircleCI and push the new gem to the repo.
Bug reports and pull requests are welcome on GitHub at https://github.com/matt-taylor/class_composer.