Class: DuckPuncher::Duck

Inherits:
Object
  • Object
show all
Defined in:
lib/duck_puncher/duck.rb

Direct Known Subclasses

UniqueDuck

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target, mod, options = {}) ⇒ Duck

Returns a new instance of Duck.

Parameters:

  • target (String, Class)

    Class or module to punch

  • mod (String, Module)

    The module that defines the extensions

  • options (Hash) (defaults to: {})

    to modify the duck #punch method behavior

Options Hash (options):

  • :only (Symbol, Array<Symbol>)

    list of methods to extend onto the target (the module must have these defined)

  • :method (Symbol, String)

    the method used to apply the module, e.g. :extend (:include)

  • :before (Proc)

    A hook that is called with the target class before punch

  • :after (Proc)

    A hook that is called with the target class after punch



12
13
14
15
16
# File 'lib/duck_puncher/duck.rb', line 12

def initialize(target, mod, options = {})
  @options = options
  @target = DuckPuncher.lookup_constant(target)
  @mod = DuckPuncher.lookup_constant(mod)
end

Instance Attribute Details

#modObject

Returns the value of attribute mod.



3
4
5
# File 'lib/duck_puncher/duck.rb', line 3

def mod
  @mod
end

#optionsObject

Returns the value of attribute options.



3
4
5
# File 'lib/duck_puncher/duck.rb', line 3

def options
  @options
end

#targetObject

Returns the value of attribute target.



3
4
5
# File 'lib/duck_puncher/duck.rb', line 3

def target
  @target
end

Instance Method Details

#call(opts = {}) ⇒ Class Also known as: punch

Returns The class that was just punched.

Parameters:

  • opts (Hash) (defaults to: {})

    to modify punch

  • options (Hash)

    a customizable set of options

Returns:

  • (Class)

    The class that was just punched



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/duck_puncher/duck.rb', line 23

def call(opts = {})
  opts = options.merge(opts)
  targets = Array(opts[:target] || self.target)
  targets.each do |target|
    opts[:before].call(target) if opts[:before]
    punches = Array(opts[:only] || Ducks::Module.instance_method(:local_methods).bind(mod).call)
    unless target.is_a?(::Module)
      fail ArgumentError, "Invalid target #{target}. Please pass a module as :target"
    end
    DuckPuncher.logger.info %Q(#{target}#{" <-- #{mod.name}#{punches}" if punches.any?})
    extender = Usable::ModExtender.new(mod, only: opts.delete(:only), method: opts.delete(:method))
    extender.call target
    opts[:after].call(target) if opts[:after]
  end
  targets
end