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