File: procto.rb

package info (click to toggle)
ruby-procto 0.0.3-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 184 kB
  • sloc: ruby: 110; makefile: 4
file content (112 lines) | stat: -rw-r--r-- 2,163 bytes parent folder | download
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