lib/usable.rb in usable-1.4.0 vs lib/usable.rb in usable-2.0.0
- old
+ new
@@ -3,25 +3,50 @@
require 'usable/version'
require 'usable/mod_extender'
require 'usable/config'
module Usable
- def usable_config
- @usable_config ||= Config.new
+
+ # @description Define an instance level version of +usables+
+ def self.extended(base)
+ base.class_eval do
+ def usables
+ self.class.usables
+ end
+
+ def usable_method(method_name)
+ self.class.usable_method(self, method_name)
+ end
+ end
+ unless base.is_a? Class
+ base.instance_eval do
+ def config(&block)
+ usables(&block)
+ end unless defined? config
+ end
+ end
end
- attr_writer :usable_config
+ # @description Read and write configuration options
+ def usables
+ @usables ||= Config.new
+ return @usables unless block_given?
+ @usables.instance_eval &Proc.new
+ end
+
+ attr_writer :usables
+
# @description Configures the +available_methods+ of a module using the given options or block and then includes it on
# the target class. Checks if there is a module named UsableSpec within the given mods namespace and uses the instance
# methods of that as the +available_methods+
#
# @example
#
# class Example
# extend Usable
- # usable Mixin, only: [:foo, :bar] do |config|
- # config.baz = "Available as `Example.usable_config.baz`"
+ # usable Mixin, only: [:foo, :bar] do
+ # baz "Available as `Example.usables.baz` or `Example.usables.mixin.baz`"
# end
# end
#
# @note Hides methods
# @note We include the primary mod when there is a UsableSpec set because any instance methods defined on the mod are
@@ -30,24 +55,33 @@
# @param [Module] mod
# @param [Hash] options Customize the extension of the module as well as define config settings on the target
# @option [Array,Symbol] :only Limit which methods are copied from the module
# @option [String,Symbol] :method (:include) The method to use for including the module
# @return [ModExtender] containing the original and modified module
- def usable(mod, options = {})
+ def usable(mod, options = {}, &block)
usable_options = { only: options.delete(:only), method: options.delete(:method) }
- if mod.respond_to? :usable_config
- mod.usable_config.to_h.each { |k, v| usable_config.public_send "#{k}=", v }
+ # Define settings on @usables and on the scoped @usables
+ scope = Config.new
+ if mod.name
+ scope_name = mod.name.split('::').last.gsub(/\B([A-Z])([a-z_0-9])/, '_\1\2').downcase
+ usables[scope_name] = scope
end
- options.each { |k, v| usable_config.public_send "#{k}=", v }
- yield usable_config if block_given?
+ if mod.respond_to? :usables
+ mod.usables.each do |k, v|
+ [scope, usables].each { |x| x.spec k, v }
+ end
+ end
+ [scope, usables].each { |x| options.each { |k, v| x[k] = v } }
+ [scope, usables].each { |x| x.instance_eval &block } if block_given?
+ # Include module
mod_ext = ModExtender.new mod, usable_options
mod_ext.use! self
mod_ext.use_original! self
mod_ext.use_class_methods! self
mod_ext
end
# @return [Method] bound to the given -context-
def usable_method(context, method_name)
- usable_config.available_methods[method_name].bind(context)
+ usables.available_methods[method_name].bind(context)
end
end