1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
# encoding: utf-8
class Procto < Module
# The default name of the instance method to be called
DEFAULT_NAME = :call
private_class_method :new
# Return a module that turns the host into a method object
#
# @example without a name
#
# class Greeter
# include Procto.call
#
# def initialize(text)
# @text = text
# end
#
# def call
# "Hello #{text}"
# end
# end
#
# Greeter.call('world') # => "Hello world"
#
# @example with a name
#
# class Printer
# include Procto.call(:print)
#
# def initialize(text)
# @text = text
# end
#
# def print
# "Hello #{text}"
# end
# end
#
# Printer.call('world') # => "Hello world"
#
# @param [#to_sym] name
# the name of the instance method to call
#
# @return [Procto]
#
# @api public
def self.call(name = DEFAULT_NAME)
new(name.to_sym)
end
# Initialize a new instance
#
# @param [Symbol] name
# the name of the instance method to call
#
# @return [undefined]
#
# @api private
def initialize(name)
@block = ->(*args) { new(*args).public_send(name) }
end
private
# Define the .call method on +host+
#
# @param [Object] host
# the hosting object
#
# @return [undefined]
#
# @api private
def included(host)
host.instance_exec(@block) do |block|
define_singleton_method(:call, &block)
end
host.extend(ClassMethods)
end
# Procto module for adding .to_proc to host class
module ClassMethods
# Return the `call` singleton method as a lambda
#
# @example using a class as a proc
#
# class Shouter
# include Procto.call
#
# def initialize(text)
# @text = text
# end
#
# def call
# "#{@text.upcase}!"
# end
# end
#
# Shouter.to_proc.call('hello') # => "HELLO!"
# %w[foo bar].map(&Shouter) # => ["FOO!", "BAR!"]
#
# @return [Proc]
#
# @api public
def to_proc
public_method(:call).to_proc
end
end
private_constant(:ClassMethods)
end # Procto
|