Sha256: 9dae3012a94cd37077a5856806a3fdeb9a3e7f6c4f64e6f0db9f768212036163

Contents?: true

Size: 1.54 KB

Versions: 3

Compression:

Stored size: 1.54 KB

Contents

module NxtSchema
  class Callable
    def initialize(callee)
      @callee = callee

      if callee.is_a?(Symbol)
        self.type = :method
      elsif callee.respond_to?(:call)
        self.type = :proc
        self.context = callee.binding
      else
        raise ArgumentError, "Callee is nor symbol nor a proc: #{callee}"
      end
    end

    def bind!(execution_context)
      self.context = execution_context
      ensure_context_not_missing
      self
    end

    def bind(execution_context = nil)
      return self if context

      self.context = execution_context
      ensure_context_not_missing
      self
    end

    # NOTE: Currently we only allow arguments! Not keyword args or **options
    # If we would allow **options and we would pass a hash as the only argument it would
    # automatically be parsed as the options!
    def call(*args)
      ensure_context_not_missing

      args = args.take(arity)

      if method?
        context.send(callee, *args)
      else
        context.instance_exec(*args, &callee)
      end
    end

    def arity
      if proc?
        callee.arity
      elsif method?
        method = context.send(:method, callee)
        method.arity
      else
        raise ArgumentError, "Can't resolve arity from #{callee}"
      end
    end

    private

    def proc?
      type == :proc
    end

    def method?
      type == :method
    end

    def ensure_context_not_missing
      return if context

      raise ArgumentError, "Missing context: #{context}"
    end

    attr_accessor :context, :callee, :type
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
nxt_schema-0.1.2 lib/nxt_schema/callable.rb
nxt_schema-0.1.1 lib/nxt_schema/callable.rb
nxt_schema-0.1.0 lib/nxt_schema/callable.rb