Skip to content

Instantly share code, notes, and snippets.

@nixpulvis
Created April 4, 2015 04:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nixpulvis/7cf7b8b0f7004e2eba66 to your computer and use it in GitHub Desktop.
Save nixpulvis/7cf7b8b0f7004e2eba66 to your computer and use it in GitHub Desktop.
Simplest Contract System in Ruby
# A Contract is one of:
# - Proc (Any -> Boolean)
# - Hash { Contract => Contract }
def assert_predicate(predicate, value)
if predicate.(value)
value
else
fail "contract error"
end
end
def assert_function(signature, function)
-> (x) do
assert(signature.values[0], function.(assert(signature.keys[0], x)))
end
end
def assert(contract, value)
case contract
when Hash
assert_function(contract, assert(-> (v) { value.is_a?(Proc) }, value))
when Proc
assert_predicate(contract, value)
end
end
is_even = -> (n) do
n % 2 == 0
end
p assert(is_even, 2)
# p assert(is_even, 3) # Contract error.
func = assert({is_even => is_even}, -> (x) { x + 2 })
p func.(2)
# p func.(3) # Contract error.
high_func = assert({{is_even => is_even} => is_even}, -> (x) { x.(4)})
p high_func.(-> (x) { x + 6 })
# p high_func.(-> (x) { x + 7 }) # Contract error.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment