strict is a rudimentary static typesystem for ruby objects - it enables easy validation of individual ruby objects and Hash sets.

For an example of validation:

require ‘typestrict’

class Rectangle

include Strict

def initialize(p)

  validate_map!({
              :width => :natural_number,
              :height => :natural_number,
              :color => :hex_color
              }, p)

  @width = p[:width]
  @height = p[:height]
  @color = p[:color]
end

def set_dimensions(dimensions)
  validate_map!({
              :width => :natural_number,
              :height => :natural_number
              }, dimensions) #checks for the presence + validity of all declared parameters

  @height = dimensions[:height]
  @width = dimensions[:width]
end

def scale_height(scale_coefficent)
  enforce!(:float, scale_coefficent)
  return scale_coefficent*@height #alays valid
end

end

Strict defines a number of ‘super-types’, currently which are: :natural_number :float :boolean :integer :numeric :character :procedure :string_array :numeric_array :float_array :integer_array :hex_color

New supertypes may be registered with the register_supertype as follows:

register_supertype(:char, proc {|data, context| enforce_primitive!(String, data); catch_error(“#{data.inspect} must be a single character in length”) unless (data.size == 1)}) registered a dynamic handler for supertype: character

> nil

irb(main)> enforce!(:char, “a”)

> “a”

irb(main)> enforce!(:char, “aa”) Strict::TypeError: TypeError caught: “aa” must be a single character in length

from (irb):6 from ./str.rb:148:in ‘call’ from ./str.rb:148:in ‘enforce!’ from (irb):8

irb(main):009:0> enforce!(:char, “x”)

> “x”

Strict simply implements an extendable static type-checker over dynamic ruby objects. For an example of validation with troublesome datasets:

#enforce!(:string_array, [“one”, “two”, 3, “four”]) #./strict.rb:3:in ‘enforce_primitive!’: 3 must be of type String (RuntimeError)

type_matrix = {

:fruit => [:apple, :orange, :banana],
:height => :natural_number,
:width => :float,
:broken => :boolean
}

invalid_data =

:fruit => :pear,
:height => -1,
:width => 100,
:broken => 1

validate_map!(type_matrix, invalid_data) #./strict.rb:27:in ‘enforce_weak_primitives!’: 1 must be of one of the types of [TrueClass, FalseClass] (RuntimeError) #./strict.rb:3:in ‘enforce_primitive!’: 10 must be of type Float (RuntimeError) #./strict.rb:38:in ‘enforce!’: pear should take on a value within [:apple, :orange, :banana] (RuntimeError) #./strict.rb:53:in ‘enforce!’: -1 must be > 0 (RuntimeError)

A valid dataset for this type_matrix would be:

valid_data = {

:fruit => :apple,
:height => 200,
:width => 100.011,
:broken => true
}

validate_map!(type_matrix, invalid_data) # => all checks pass