lib/usable/mod_extender.rb in usable-1.2.1 vs lib/usable/mod_extender.rb in usable-1.3.0

- old
+ new

@@ -1,35 +1,62 @@ module Usable class ModExtender attr_reader :name - attr_accessor :copy, :mod, :config + attr_accessor :copy, :mod, :options - def initialize(mod, config = OpenStruct.new) + def initialize(mod, options = {}) @mod = mod + @options = options + @options[:method] ||= :include if has_spec? @copy = mod.const_get(:UsableSpec).dup @name = "#{mod.name}UsableSpec" else - @copy = mod.dup + @copy = mod.dup @name = mod.name end - @config = config end - # @note Destructive def call override copy end + # @note Destructive, as it changes the dup'd mod def override - unwanted = config.only ? copy.instance_methods - Array(config.only) : [] + unwanted = options[:only] ? copy.instance_methods - Array(options[:only]) : [] unwanted.each do |method_name| copy.send :remove_method, method_name end end + # @description Directly include a module whose methods you want made available in +usable_config.available_methods+ + # Gives the module a name when including so that it shows up properly in the list of ancestors + def use!(target) + const_name = "#{mod_name}Used" + override + target.send :remove_const, const_name if target.const_defined? const_name, false + target.const_set const_name, copy + target.usable_config.modules << copy + target.send options[:method], copy + end + + # @description Sends the method to the target with the original module + def use_original!(target) + return unless has_spec? + target.usable_config.modules << mod + target.send options[:method], mod + end + def has_spec? mod.const_defined?(:UsableSpec) + end + + def mod_name + if name + name.split('::').last + else + "UsableMod#{Time.now.strftime('%s')}" + end end end end