# Usable [![Gem Version](https://badge.fury.io/rb/usable.svg)](http://badge.fury.io/rb/usable) [![Build Status](https://travis-ci.org/ridiculous/usable.svg)](https://travis-ci.org/ridiculous/usable) [![Code Climate](https://codeclimate.com/github/ridiculous/usable/badges/gpa.svg)](https://codeclimate.com/github/ridiculous/usable) An elegant way to mount and configure your modules. Usable gives you control over which methods are included, and a simple interface to help you call dynamic methods with confidence. ```ruby module VersionMixin def save_version "Saving up to #{self.class.usable_config.max_versions} versions to #{self.class.usable_config.table_name}" end def destroy_version "Deleting versions from #{self.class.usable_config.table_name}" end end class Model extend Usable usable VersionMixin, only: :save_version do |config| config.max_versions = 10 config.table_name = 'custom_versions' end def save self.class.usable_method(self, :save_version).call end end model = Model.new model.save_version # => "Saving up to 10 versions to custom_versions" model.destroy_version # => NoMethodError: undefined method `destroy_version' for # "Saving up to 10 versions to custom_versions" Model.usable_method(model, :destroy_version).call # => nil ``` ## Module Naming Conventions Modules with the following names found within the target module's namespace will be automatically used. `ClassMethods` - extended onto the target module. `UsableSpec` - tells usable which methods are configurable via the `:only` option. Any naming conflicts will be resolved by giving precedence to the parent module. For example: ```ruby module Mixin def name "defined by Mixin" end def from_mixin "always here" end # @description Usable will apply the :only option to just the methods defined by this module module UsableSpec def from_spec "can be excluded" end def name "defined by UsableSpec" end end end class Example extend Usable usable Mixin, only: :from_spec end Example.new.from_spec # => "can be excluded" Example.new.from_mixin # => "always here" Example.new.name # => "defined by Mixin" Example.ancestors # => [Example, Mixin, Example::MixinUsableSpecUsed, Object, Kernel, BasicObject] (ruby -v 2.3.0) ``` ## Notes If the given module is modified by the `:only` option, then Usable will duplicate the module so that it doesn't mutate it globally. Duplicating a module returns an anonymous module. But anonymous mods in the ancestor list can be confusing. So Usable gives the modified module a name, which is the same name as the original module but with "Used" appended. ```ruby Mixin => MixinUsed ``` ## Installation Add this line to your application's Gemfile: ```ruby gem 'usable' ``` ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/ridiculous/usable.