module TinyTyping

Constants

VERSION

Public Class Methods

test!(value, *types) click to toggle source
# File lib/tinytyping.rb, line 72
def test!(value, *types)
  Tester.new(*types).run!(value)
end
test?(*args) click to toggle source
# File lib/tinytyping.rb, line 65
def test?(*args)
  test!(*args)
  true
rescue ArgumentError
  false
end

Private Class Methods

decorate(airty, &block) click to toggle source
# File lib/tinytyping.rb, line 107
def decorate(airty, &block)
  @next_decorator_airty = airty
  @next_decorator = block
  @prev_added_method = nil
end
included(base) click to toggle source
# File lib/tinytyping.rb, line 78
def included(base)
  base.class_eval do
    private

    def test!(*args)
      TinyTyping.test!(*args)
    end

    class << self
      private

      def method_added(method)
        return unless @next_decorator

        unbound_method = instance_method(method)

        if unbound_method.arity == @next_decorator_airty && (@prev_added_method.nil? || method.to_s == "#{@prev_added_method}=")
          decorator = @next_decorator
          @next_decorator = @prev_added_method = nil
          define_method(method) do |*args, &block|
            decorator.call(unbound_method.bind(self), *args, &block)
          end
        elsif unbound_method.arity.zero? && @prev_added_method.nil?
          @prev_added_method = method
        else
          raise ArgumentError, "#{method}.arity(#{unbound_method.arity}) does not match decorator's arity(#{@next_decorator_airty})"
        end
      end

      def decorate(airty, &block)
        @next_decorator_airty = airty
        @next_decorator = block
        @prev_added_method = nil
      end

      def typed(*types)
        return if types.empty?

        decorate(types.size) do |method, *args, &block|
          types.each_with_index do |type, index|
            TinyTyping.test!(args[index], *(Array.try_convert(type) || [type]))
          end
          method.call(*args, &block)
        end
      end
    end
  end
end
method_added(method) click to toggle source
# File lib/tinytyping.rb, line 89
def method_added(method)
  return unless @next_decorator

  unbound_method = instance_method(method)

  if unbound_method.arity == @next_decorator_airty && (@prev_added_method.nil? || method.to_s == "#{@prev_added_method}=")
    decorator = @next_decorator
    @next_decorator = @prev_added_method = nil
    define_method(method) do |*args, &block|
      decorator.call(unbound_method.bind(self), *args, &block)
    end
  elsif unbound_method.arity.zero? && @prev_added_method.nil?
    @prev_added_method = method
  else
    raise ArgumentError, "#{method}.arity(#{unbound_method.arity}) does not match decorator's arity(#{@next_decorator_airty})"
  end
end
typed(*types) click to toggle source
# File lib/tinytyping.rb, line 113
def typed(*types)
  return if types.empty?

  decorate(types.size) do |method, *args, &block|
    types.each_with_index do |type, index|
      TinyTyping.test!(args[index], *(Array.try_convert(type) || [type]))
    end
    method.call(*args, &block)
  end
end