# 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