lib/usable.rb in usable-0.2.0 vs lib/usable.rb in usable-0.3.0
- old
+ new
@@ -1,61 +1,42 @@
require "ostruct"
+require "delegate"
require "usable/version"
module Usable
+
+ autoload :ModExtender, 'usable/mod_extender'
+ autoload :Config, 'usable/config'
+
def usable_config
@usable_config ||= Config.new
end
+ attr_writer :usable_config
- alias_method :config, :usable_config unless method_defined?(:config)
-
+ # @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 Spec within the given mods namespace and uses the instance of
+ # methods of that as the +available_methods+
+ #
+ # @example
+ #
+ # class Example
+ # extend Usable
+ # usable VersionKit, only: :save_version
+ # end
+ #
+ # @note Hides methods
+ # @note We include the primary mod when there is a Spec set because any instance method defined on the mod are not
+ # configurable and should therefore takes precedence over those defined in the Spec
def usable(mod, options = {})
options.each { |k, v| usable_config.public_send "#{k}=", v }
- if block_given?
- yield usable_config
- end
- wrapped_mod = spec(mod).dup
- wrapped_mod.prepend build_null_mod(wrapped_mod)
- usable_config.modules[mod] = wrapped_mod
- if has_spec?(mod)
- send :include, mod
- else
- send :include, usable_config.modules[mod]
- end
+ yield usable_config if block_given?
+ mod_ext = ModExtender.new mod, usable_config
+ usable! mod_ext.call
+ usable! mod if mod_ext.has_spec?
end
- # @description Stub out any "unwanted" methods
- def build_null_mod(mod)
- unwanted = usable_config.only ? mod.instance_methods - Array(usable_config.only) : []
- Module.new do
- unwanted.each do |method_name|
- define_method(method_name) { |*| }
- end
- end
- end
-
- def has_spec?(mod)
- mod.const_defined?(:Spec)
- end
-
- def spec(mod)
- if has_spec?(mod)
- mod.const_get(:Spec)
- else
- mod
- end
- end
-
- class Config < OpenStruct
- def available_methods
- modules.each_with_object({}) do |(_, mod_copy), result|
- mod_copy.instance_methods.each do |method_name|
- result[method_name] = mod_copy.instance_method method_name
- end
- end
- end
-
- def modules
- @modules ||= {}
- end
+ # @description Directly include a module whose methods you want made available in +usable_config.available_methods+
+ def usable!(mod)
+ usable_config.modules << mod
+ send :include, mod
end
end