Module: Taipo::Check

Defined in:
lib/taipo/check.rb

Overview

A dedicated namespace for methods meant to be included by the user

Since:

  • 1.0.0

Instance Method Summary collapse

Instance Method Details

#check(context, collect_invalids = false, **checks) ⇒ Array

Check whether the given arguments match the given type definition in the given context

Examples:

require 'taipo/taipo'

class A
  include Taipo::Check

  def foo(str)
    check types, str: 'String'
    puts str
  end

  def bar(str)
    check types, str: 'Integer'
    puts str
  end
end

a = A.new()
a.foo('Hello world!')     #=> "Hello world!"
a.bar('Goodbye world!')   #=> raise Taipo::TypeError

Parameters:

  • context (Binding)

    the context in which the arguments to be checked are defined

  • collect_invalids (Boolean) (defaults to: false)

    whether to raise an exception for, or collect, an argument that doesn't match its type definition

  • checks (Hash)

    the arguments to be checked written as Symbol: String pairs with the Symbol being the name of the argument and the String being its type definition

Returns:

  • (Array)

    the arguments which don't match (ie. an empty array if all arguments match)

Raises:

  • (::TypeError)

    if the context is not a Binding

  • (Taipo::SyntaxError)

    if the type definitions in checks are invalid

  • (Taipo::TypeError)

    if the arguments in checks don't match the given type definition

Since:

  • 1.0.0


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
# File 'lib/taipo/check.rb', line 61

def check(context, collect_invalids = false, **checks)
  msg = "The first argument to this method must be of type Binding."
  raise TypeError, msg unless context.is_a? Binding

  checks.reduce(Array.new) do |memo,(k,v)|
    arg = if k[0] == '@' && self.instance_variable_defined?(k)
            self.instance_variable_get k
          elsif k[0] != '@' && context.local_variable_defined?(k)
            context.local_variable_get k
          else
            msg = "Argument '#{k}' is not defined."
            raise Taipo::NameError, msg
          end

    types = if hit = Taipo::Cache[v]
              hit
            else
              Taipo::Cache[v] = Taipo::Parser.parse v
            end

    is_match = types.any? { |t| t.match? arg }

    unless collect_invalids || is_match
      if Taipo::instance_method? v
        msg = "Object '#{k}' does not respond to #{v}."
      elsif arg.is_a? Enumerable
        type_string = arg.class.name + Taipo.child_types_string(arg)
        msg = "Object '#{k}' is #{type_string} but expected #{v}."
      else
        msg = "Object '#{k}' is #{arg.class.name} but expected #{v}."
      end
      raise Taipo::TypeError, msg
    end

    (is_match) ? memo : memo.push(k)
  end
end

#review(context, **checks) ⇒ Array

Review whether the given arguments match the given type definition in the given context

This is a convenience method for calling #check with collect_invalids set to true.

Parameters:

  • context (Binding)

    the context in which the arguments to be checked are defined

  • checks (Hash)

    the arguments to be checked written as Symbol: String pairs with the Symbol being the name of the argument and the String being its type definition

Returns:

  • (Array)

    the arguments which don't match (ie. an empty array if all arguments match)

Raises:

  • (::TypeError)

    if the context is not a Binding

  • (Taipo::SyntaxError)

    if the type definitions in checks are invalid

  • (Taipo::TypeError)

    if the arguments in checks don't match the given type definition

Since:

  • 1.0.0


113
114
115
# File 'lib/taipo/check.rb', line 113

def review(context, **checks)
  self.check(context, true, checks)
end