Sha256: a8ae4f166ae9e7767671cfd3eeaa2246be054c80c2015875074b92e9f22bae31

Contents?: true

Size: 1.2 KB

Versions: 5

Compression:

Stored size: 1.2 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, **kwargs, &block)
        new.(*args, **kwargs, &block)
      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

5 entries across 5 versions & 1 rubygems

Version Path
junk_drawer-2.1.2 lib/junk_drawer/callable.rb
junk_drawer-2.1.1 lib/junk_drawer/callable.rb
junk_drawer-2.1.0 lib/junk_drawer/callable.rb
junk_drawer-2.0.0 lib/junk_drawer/callable.rb
junk_drawer-1.6.2 lib/junk_drawer/callable.rb