Sha256: b68ced55dbedb13584420af9690f56c72d8f6f601a0a84796da48740c2435b47

Contents?: true

Size: 1.16 KB

Versions: 3

Compression:

Stored size: 1.16 KB

Contents

# frozen_string_literal: true

module JunkDrawer
  # error to be thrown by Callable
  class CallableError < StandardError
  end

  # module to constrain interfaces of classes to just `call`
  module Callable
    def call
      raise NotImplementedError
    end

    def to_proc
      proc { |args| self.(*args) }
    end

    # `ClassMethods` defines a class level method `call` that delegates to
    # an instance. It also causes an error to be raised if a public instance
    # method is defined with a name other than `call`
    module ClassMethods
      def call(*args)
        new.(*args)
      end

      def to_proc
        new.to_proc
      end

      def method_added(method_name)
        return if valid_callable_method?(method_name)

        raise CallableError, "invalid method name #{method_name}, " \
                            'only public method allowed is "call"'
      end

    private

      def valid_callable_method?(method_name)
        method_name == :call ||
          !public_method_defined?(method_name) ||
          method_name.to_s.start_with?('__')
      end
    end

    def self.included(base)
      base.public_send(:extend, ClassMethods)
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
junk_drawer-1.4.0 lib/junk_drawer/callable.rb
junk_drawer-1.3.0 lib/junk_drawer/callable.rb
junk_drawer-1.2.1 lib/junk_drawer/callable.rb