From 9f5dc400b11e2dedf63f6954a0606868d0ee64a5 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Sun, 1 Jul 2012 12:59:05 -0700 Subject: [PATCH 01/19] Create gh-pages branch via GitHub --- images/checker.png | Bin 0 -> 250 bytes index.html | 502 +++++++++++++++++++++++++++++++++++ javascripts/scale.fix.js | 20 ++ params.json | 1 + stylesheets/pygment_trac.css | 60 +++++ stylesheets/styles.css | 356 +++++++++++++++++++++++++ 6 files changed, 939 insertions(+) create mode 100644 images/checker.png create mode 100644 index.html create mode 100644 javascripts/scale.fix.js create mode 100644 params.json create mode 100644 stylesheets/pygment_trac.css create mode 100644 stylesheets/styles.css diff --git a/images/checker.png b/images/checker.png new file mode 100644 index 0000000000000000000000000000000000000000..ab1454032c6ec47a4c974f4e4d75bd226911b4fc GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^3P3E!!3HFKxnwkf6icy_X9x!n)NrJ90QsB+9+AZi z4BSE>%y{W;-5;Q!Oo?kmNpOBzNqJ&XDuZK6ep0G}TV_#ed45rLv4V53Y2nt#W z{&tJwQo64!`zEoY0VG=WX{H35gh8JhW7>iX;yrE$GemF_3=9!wFW${k`+fjuK7*&L KpUXO@geCwfrcS5; literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..11471a9 --- /dev/null +++ b/index.html @@ -0,0 +1,502 @@ + + + + + + Contracts.ruby by egonSchiele + + + + + + + + + +
+
+

Contracts.ruby

+

Contracts for Ruby

+

View the Project on GitHub egonSchiele/contracts.ruby

+ +
+
+

The contracts.ruby tutorial

+ +

Introduction

+ +

contracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you

+ +
    +
  • catch bugs faster
  • +
  • make it very easy to catch certain types of bugs
  • +
  • make sure that the user gets proper messaging when a bug occurs.
  • +

Installation

+ +
gem install contracts
+
+ +

Basics

+ +

A simple example:

+ +
+
Contract Num, Num => Num
+def add(a, b)
+   a + b
+ end
+
+
+ + +

Here, the contract is Contract Num, Num => Num. This says that the add function takes two numbers and returns a number.

+ +

Copy this code into a file and run it:

+ +
+
require 'contracts'
+include Contracts
+
+Contract Num, Num => Num
+def add(a, b)
+   a + b
+end
+
+puts add(1, "foo")
+
+
+ + +

You'll see a detailed error message like so:

+ +
./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)
+    Expected: Contracts::Num,
+    Actual: "foo"
+    Value guarded in: Object::add
+    With Contract: Contracts::Num, Contracts::Num
+    At: foo.rb:6 
+
+ +

That tells you that your contract was violated! add expected a Num, and got a string ("foo") instead. +By default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.

+ +

Builtin Contracts

+ +

Num is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the Contracts namespace. The easiest way to use them is to put include Contracts at the top of your file, but beware that they will pollute your namespace with new class names.

+ +

contracts.ruby comes with a lot of builtin contracts, including:

+ +
Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, IsA, ArrayOf
+
+ +

To see all the builtin contracts and what they do, check out the rdoc.

+ +

More Examples

+ +

Hello, World

+ +
+
Contract String => nil
+def hello(name)
+  puts "hello, #{name}!"
+end
+
+
+ + +

You always need to specify a contract for the return value. In this example, hello doesn't return anything, so the contract is nil. Now you know that you can use a constant like nil as the of a contract. Valid values for a contract are:

+ +
    +
  • the name of a class (like String or Fixnum)
  • +
  • a constant (like nil or 1)
  • +
  • a Proc that takes a value and returns true or false to indicate whether the contract passed or not
  • +
  • a class that responds to the valid? class method (more on this later)
  • +
  • an instance of a class that responds to the valid? method (more on this later)
  • +

A Double Function

+ +
+
Contract Or[Fixnum, Float] => Or[Fixnum, Float]
+def double(x)
+  2 * x
+end
+
+
+ + +

Sometimes you want to be able to choose between a few contracts. Or takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the Or contract passes. +This introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the valid? method. This is what Or[Fixnum, Float] is. The longer way to write it would have been:

+ +
+
Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
+
+
+ + +

All the builtin contracts have overridden the square brackets ([]) to give the same functionality. So you could write

+ +
+
Contract Or[Fixnum, Float] => Or[Fixnum, Float]
+
+
+ + +

or

+ +
+
Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
+
+
+ + +

whichever you prefer. They both mean the same thing here: make a new instance of Or with Fixnum and Float. Use that instance to validate the argument.

+ +

A Product Function

+ +
+
Contract ArrayOf[Num] => Num
+def product(vals)
+  total = 1
+  vals.each do |val|
+    total *= val
+  end
+  total
+end
+
+
+ + +

This contract uses the ArrayOf contract. Here's how ArrayOf works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.

+ +
+
# passes
+product([1, 2, 3, 4])
+
+# fails
+product([1, 2, 3, "foo"])
+
+
+ + +

Another Product Function

+ +
+
Contract Args[Num] => Num
+def product(*vals)
+  total = 1
+  vals.each do |val|
+    total *= val
+  end
+  total
+end
+
+
+ + +

This function uses varargs (*args) instead of an array. To make a contract on varargs, use the Args contract. It takes one contract as an argument and uses it to validate every element passed in through *args. So for example,

+ +

Args[Num] means they should all be numbers.

+ +

Args[Or[Num, String]] means they should all be numbers or strings.

+ +

Args[Any] means all arguments are allowed (Any is a contract that passes for any argument).

+ +

Contracts On Arrays

+ +

If an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:

+ +
+
# a function that takes an array of two elements...a person's age and a person's name.
+Contract [Num, String] => nil
+def person(data)
+  p data
+end
+
+
+ + +

If you don't know how many elements it's going to have, use ArrayOf.

+ +

Contracts On Hashes

+ +

Here's a contract that requires a Hash. We can put contracts on each of the keys:

+ +
+
# note the parentheses around the hash; without those you would get a syntax error
+Contract ({ :age => Num, :name => String }) => nil
+def person(data)
+  p data
+end
+
+
+ + +

Then if someone tries to call the function with bad data, it will fail:

+ +
+
# error: age can't be nil!
+person({:name => "Adit", :age => nil})
+
+
+ + +

You don't need to put a contract on every key. So this call would succeed:

+ +
+
# error: age can't be nil!
+person({:name => "Adit", :age => nil, :foo => "bar"})
+
+
+ + +

even though we don't specify a type for :foo.

+ +

Contracts On Functions

+ +

If you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can! +Use the Func contract. Func takes a contract as it's argument, and uses that contract on the function that you pass in.

+ +

Here's a map function that requires an array of numbers, and a function that takes a number and returns a number:

+ +
+
Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]
+def map(arr, func)
+  ret = []
+  arr.each do |x|
+    ret << func[x]
+  end
+  ret
+end
+
+
+ + +

This will add the contract Num => Num on func. Try it with these two examples:

+ +
+
p map([1, 2, 3], lambda { |x| x + 1 }) # works
+p map([1, 2, 3], lambda { |x| "oops" }) # fails, the lambda returns a string.
+
+
+ + +

Returning Multiple Values

+ +

Treat the return value as an array. For example, here's a function that returns two numbers:

+ +
+
Contract Num => [Num, Num]
+def mult(x)
+  return x, x+1
+end
+
+
+ + +

Synonyms For Contracts

+ +

If you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a Hash or nil. If a Hash is returned, it contains information about a person. Your contact might look like this:

+ +
+
Contract String => Or[Hash, nil]
+def some_func(str)
+
+
+ + +

You can make your contract more meaningful with a synonym:

+ +
+
# the synonym
+Person = Or[Hash, nil]
+
+# use the synonym here
+Contract String => Person
+def some_func(str)
+
+
+ + +

Now you can use Person wherever you would have used Or[Hash, nil]. Your code is now cleaner and more clearly says what the function is doing.

+ +

Defining Your Own Contracts

+ +

Contracts are very easy to define. To re-iterate, there are 5 kinds of contracts:

+ +
    +
  • the name of a class (like String or Fixnum)
  • +
  • a constant (like nil or 1)
  • +
  • a Proc that takes a value and returns true or false to indicate whether the contract passed or not
  • +
  • a class that responds to the valid? class method (more on this later)
  • +
  • an instance of a class that responds to the valid? method (more on this later)
  • +

The first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:

+ +

A Proc

+ +
+
Contract lambda { |x| x.is_a? Numeric } => Num
+def double(x)
+
+
+ + +

The lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a Numeric. If it is, it returns true. Otherwise it returns false. +It's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:

+ +

A Class With valid? As a Class Method

+ +

Here's how the Num class is defined. It does exactly what the lambda did in the previous example:

+ +
+
class Num
+  def self.valid? val
+    val.is_a? Numeric
+  end
+end
+
+
+ + +

The valid? class method takes one parameter: the argument that is getting passed to the function. It returns true or false.

+ +

A Class With valid? As an Instance Method

+ +

Here's how the Or class is defined:

+ +
+
class Or < CallableClass
+  def initialize(*vals)
+    @vals = vals
+  end
+
+  def valid?(val)
+    @vals.any? do |contract|
+      res, _ = Contract.valid?(val, contract)
+      res
+    end
+  end
+end
+
+
+ + +

The Or contract takes a sequence of contracts, and passes if any of them pass. It uses Contract.valid? to validate the value against the contracts.

+ +

This class inherits from CallableClass, which allows us to use [] when using the class:

+ +
+
Contract Or[Fixnum, Float] => Num
+def double(x)
+  2 * x
+end
+
+
+ + +

Without CallableClass, we would have to use .new instead:

+ +
+
Contract Or.new(Fixnum, Float) => Num
+def double(x)
+# etc
+
+
+ + +

You can use CallableClass in your own contracts to make them callable using [].

+ +

Customizing Error Messages

+ +

When a contract fails, part of the error message prints the contract:

+ +
...
+Expected: Contracts::Num,
+...
+
+ +

You can customize this message by overriding the to_s method on your class or proc. For example, suppose we overrode Num's to_s method:

+ +
+
def Num.to_s
+  "a number please"
+end
+
+
+ + +

Now the error says:

+ +
...
+Expected: a number please,
+...
+
+ +

Failure and Success Callbacks

+ +

Supposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.

+ +

contracts.ruby provides a failure_callback that gets called when a contract fails. By monkeypatching failure_callback, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:

+ +
+
class Contract
+  def self.failure_callback(data)
+    info failure_msg(data)
+  end
+end
+
+
+ + +

failure_msg is a function that prints out information about the failure. failure_callback takes a hash with the following values:

+ +
{
+  :arg => the argument to the method,
+  :contract => the contract that got violated,
+  :class => the method's class,
+  :method => the method,
+  :contracts => a list of contracts on the method
+}
+
+ +

There's also a success_callback that gets called when a contract succeeds. It doesn't do anything by default, but you can monkeypatch it to do whatever you would like.

+ +

If either callback returns false, the method that the contract is guarding will not be called.

+ +

Gotchas

+ +

Contracts don't work on top level functions. Any function with a contract should be in a class.

+ +

Misc

+ +

Please submit any bugs here and I'll try to get them resolved ASAP!

+ +

See any mistakes in this tutorial? I try to make it bug-free, but they can creep in. File an issue.

+ +

If you're using the library, please let me know what project you're using it on :)

+ +

Happy Coding!

+
+
+ + + + + + + \ No newline at end of file diff --git a/javascripts/scale.fix.js b/javascripts/scale.fix.js new file mode 100644 index 0000000..08716c0 --- /dev/null +++ b/javascripts/scale.fix.js @@ -0,0 +1,20 @@ +fixScale = function(doc) { + + var addEvent = 'addEventListener', + type = 'gesturestart', + qsa = 'querySelectorAll', + scales = [1, 1], + meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; + + function fix() { + meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; + doc.removeEventListener(type, fix, true); + } + + if ((meta = meta[meta.length - 1]) && addEvent in doc) { + fix(); + scales = [.25, 1.6]; + doc[addEvent](type, fix, true); + } + +}; \ No newline at end of file diff --git a/params.json b/params.json new file mode 100644 index 0000000..17cc61c --- /dev/null +++ b/params.json @@ -0,0 +1 @@ +{"note":"Don't delete this file! It's used internally to help with page regeneration.","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\n end\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6 \r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, IsA, ArrayOf\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers. \r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure and Success Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => a list of contracts on the method\r\n }\r\n\r\nThere's also a `success_callback` that gets called when a contract succeeds. It doesn't do anything by default, but you can monkeypatch it to do whatever you would like.\r\n\r\nIf either callback returns `false`, the method that the contract is guarding will not be called.\r\n\r\n## Gotchas\r\n\r\nContracts don't work on top level functions. Any function with a contract should be in a class.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nHappy Coding!","name":"Contracts.ruby","google":"UA-29851666-1","tagline":"Contracts for Ruby"} \ No newline at end of file diff --git a/stylesheets/pygment_trac.css b/stylesheets/pygment_trac.css new file mode 100644 index 0000000..1926cfd --- /dev/null +++ b/stylesheets/pygment_trac.css @@ -0,0 +1,60 @@ +.highlight .hll { background-color: #49483e } +.highlight { background: #3A3C42; color: #f8f8f2 } +.highlight .c { color: #75715e } /* Comment */ +.highlight .err { color: #960050; background-color: #1e0010 } /* Error */ +.highlight .k { color: #66d9ef } /* Keyword */ +.highlight .l { color: #ae81ff } /* Literal */ +.highlight .n { color: #f8f8f2 } /* Name */ +.highlight .o { color: #f92672 } /* Operator */ +.highlight .p { color: #f8f8f2 } /* Punctuation */ +.highlight .cm { color: #75715e } /* Comment.Multiline */ +.highlight .cp { color: #75715e } /* Comment.Preproc */ +.highlight .c1 { color: #75715e } /* Comment.Single */ +.highlight .cs { color: #75715e } /* Comment.Special */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .kc { color: #66d9ef } /* Keyword.Constant */ +.highlight .kd { color: #66d9ef } /* Keyword.Declaration */ +.highlight .kn { color: #f92672 } /* Keyword.Namespace */ +.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ +.highlight .kr { color: #66d9ef } /* Keyword.Reserved */ +.highlight .kt { color: #66d9ef } /* Keyword.Type */ +.highlight .ld { color: #e6db74 } /* Literal.Date */ +.highlight .m { color: #ae81ff } /* Literal.Number */ +.highlight .s { color: #e6db74 } /* Literal.String */ +.highlight .na { color: #a6e22e } /* Name.Attribute */ +.highlight .nb { color: #f8f8f2 } /* Name.Builtin */ +.highlight .nc { color: #a6e22e } /* Name.Class */ +.highlight .no { color: #66d9ef } /* Name.Constant */ +.highlight .nd { color: #a6e22e } /* Name.Decorator */ +.highlight .ni { color: #f8f8f2 } /* Name.Entity */ +.highlight .ne { color: #a6e22e } /* Name.Exception */ +.highlight .nf { color: #a6e22e } /* Name.Function */ +.highlight .nl { color: #f8f8f2 } /* Name.Label */ +.highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +.highlight .nx { color: #a6e22e } /* Name.Other */ +.highlight .py { color: #f8f8f2 } /* Name.Property */ +.highlight .nt { color: #f92672 } /* Name.Tag */ +.highlight .nv { color: #f8f8f2 } /* Name.Variable */ +.highlight .ow { color: #f92672 } /* Operator.Word */ +.highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +.highlight .mf { color: #ae81ff } /* Literal.Number.Float */ +.highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ +.highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ +.highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ +.highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ +.highlight .sc { color: #e6db74 } /* Literal.String.Char */ +.highlight .sd { color: #e6db74 } /* Literal.String.Doc */ +.highlight .s2 { color: #e6db74 } /* Literal.String.Double */ +.highlight .se { color: #ae81ff } /* Literal.String.Escape */ +.highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ +.highlight .si { color: #e6db74 } /* Literal.String.Interpol */ +.highlight .sx { color: #e6db74 } /* Literal.String.Other */ +.highlight .sr { color: #e6db74 } /* Literal.String.Regex */ +.highlight .s1 { color: #e6db74 } /* Literal.String.Single */ +.highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ +.highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ +.highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ +.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ +.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/stylesheets/styles.css b/stylesheets/styles.css new file mode 100644 index 0000000..466b9d6 --- /dev/null +++ b/stylesheets/styles.css @@ -0,0 +1,356 @@ +@import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700); +html { + background: #6C7989; + background: #6c7989 -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #6c7989), color-stop(100%, #434b55)) fixed; + background: #6c7989 -webkit-linear-gradient(#6c7989, #434b55) fixed; + background: #6c7989 -moz-linear-gradient(#6c7989, #434b55) fixed; + background: #6c7989 -o-linear-gradient(#6c7989, #434b55) fixed; + background: #6c7989 -ms-linear-gradient(#6c7989, #434b55) fixed; + background: #6c7989 linear-gradient(#6c7989, #434b55) fixed; +} + +body { + padding: 50px 0; + margin: 0; + font: 14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #555; + font-weight: 300; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAeCAYAAABNChwpAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAAUdEVYdENyZWF0aW9uIFRpbWUAMy82LzEygrTcTAAAAFRJREFUSIljfPDggZRf5RIGGNjUHsNATz6jXmSL1Kb2GLiAX+USBnrymRgGGDCORgFmoNAXjEbBaBSMRsFoFIxGwWgUjEbBaBSMRsFoFIxGwWgUAABYNujumib3wAAAAABJRU5ErkJggg==') fixed; +} + +.wrapper { + width: 640px; + margin: 0 auto; + background: #DEDEDE; + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + -ms-border-radius: 8px; + -o-border-radius: 8px; + border-radius: 8px; + -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; + -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; + box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; +} + +header, section, footer { + display: block; +} + +a { + color: #069; + text-decoration: none; +} + +p { + margin: 0 0 20px; + padding: 0; +} + +strong { + color: #222; + font-weight: 700; +} + +header { + -webkit-border-radius: 8px 8px 0 0; + -moz-border-radius: 8px 8px 0 0; + -ms-border-radius: 8px 8px 0 0; + -o-border-radius: 8px 8px 0 0; + border-radius: 8px 8px 0 0; + background: #C6EAFA; + background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ddfbfc), color-stop(100%, #c6eafa)); + background: -webkit-linear-gradient(#ddfbfc, #c6eafa); + background: -moz-linear-gradient(#ddfbfc, #c6eafa); + background: -o-linear-gradient(#ddfbfc, #c6eafa); + background: -ms-linear-gradient(#ddfbfc, #c6eafa); + background: linear-gradient(#ddfbfc, #c6eafa); + position: relative; + padding: 15px 20px; + border-bottom: 1px solid #B2D2E1; +} +header h1 { + margin: 0; + padding: 0; + font-size: 24px; + line-height: 1.2; + color: #069; + text-shadow: rgba(255, 255, 255, 0.9) 0 1px 0; +} +header.without-description h1 { + margin: 10px 0; +} +header p { + margin: 0; + color: #61778B; + width: 300px; + font-size: 13px; +} +header p.view { + display: none; + font-weight: 700; + text-shadow: rgba(255, 255, 255, 0.9) 0 1px 0; + -webkit-font-smoothing: antialiased; +} +header p.view a { + color: #06c; +} +header p.view small { + font-weight: 400; +} +header ul { + margin: 0; + padding: 0; + list-style: none; + position: absolute; + z-index: 1; + right: 20px; + top: 20px; + height: 38px; + padding: 1px 0; + background: #5198DF; + background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #77b9fb), color-stop(100%, #3782cd)); + background: -webkit-linear-gradient(#77b9fb, #3782cd); + background: -moz-linear-gradient(#77b9fb, #3782cd); + background: -o-linear-gradient(#77b9fb, #3782cd); + background: -ms-linear-gradient(#77b9fb, #3782cd); + background: linear-gradient(#77b9fb, #3782cd); + border-radius: 5px; + -webkit-box-shadow: inset rgba(255, 255, 255, 0.45) 0 1px 0, inset rgba(0, 0, 0, 0.2) 0 -1px 0; + -moz-box-shadow: inset rgba(255, 255, 255, 0.45) 0 1px 0, inset rgba(0, 0, 0, 0.2) 0 -1px 0; + box-shadow: inset rgba(255, 255, 255, 0.45) 0 1px 0, inset rgba(0, 0, 0, 0.2) 0 -1px 0; + width: auto; +} +header ul:before { + content: ''; + position: absolute; + z-index: -1; + left: -5px; + top: -4px; + right: -5px; + bottom: -6px; + background: rgba(0, 0, 0, 0.1); + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + -ms-border-radius: 8px; + -o-border-radius: 8px; + border-radius: 8px; + -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0, inset rgba(255, 255, 255, 0.7) 0 -1px 0; + -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0, inset rgba(255, 255, 255, 0.7) 0 -1px 0; + box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0, inset rgba(255, 255, 255, 0.7) 0 -1px 0; +} +header ul li { + width: 79px; + float: left; + border-right: 1px solid #3A7CBE; + height: 38px; +} +header ul li.single { + border: none; +} +header ul li + li { + width: 78px; + border-left: 1px solid #8BBEF3; +} +header ul li + li + li { + border-right: none; + width: 79px; +} +header ul a { + line-height: 1; + font-size: 11px; + color: #fff; + color: rgba(255, 255, 255, 0.8); + display: block; + text-align: center; + font-weight: 400; + padding-top: 6px; + height: 40px; + text-shadow: rgba(0, 0, 0, 0.4) 0 -1px 0; +} +header ul a strong { + font-size: 14px; + display: block; + color: #fff; + -webkit-font-smoothing: antialiased; +} + +section { + padding: 15px 20px; + font-size: 15px; + border-top: 1px solid #fff; + background: -webkit-gradient(linear, 50% 0%, 50% 700, color-stop(0%, #fafafa), color-stop(100%, #dedede)); + background: -webkit-linear-gradient(#fafafa, #dedede 700px); + background: -moz-linear-gradient(#fafafa, #dedede 700px); + background: -o-linear-gradient(#fafafa, #dedede 700px); + background: -ms-linear-gradient(#fafafa, #dedede 700px); + background: linear-gradient(#fafafa, #dedede 700px); + -webkit-border-radius: 0 0 8px 8px; + -moz-border-radius: 0 0 8px 8px; + -ms-border-radius: 0 0 8px 8px; + -o-border-radius: 0 0 8px 8px; + border-radius: 0 0 8px 8px; + position: relative; +} + +h1, h2, h3, h4, h5, h6 { + color: #222; + padding: 0; + margin: 0 0 20px; + line-height: 1.2; +} + +p, ul, ol, table, pre, dl { + margin: 0 0 20px; +} + +h1, h2, h3 { + line-height: 1.1; +} + +h1 { + font-size: 28px; +} + +h2 { + color: #393939; +} + +h3, h4, h5, h6 { + color: #494949; +} + +blockquote { + margin: 0 -20px 20px; + padding: 15px 20px 1px 40px; + font-style: italic; + background: #ccc; + background: rgba(0, 0, 0, 0.06); + color: #222; +} + +img { + max-width: 100%; +} + +code, pre { + font-family: Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + color: #333; + font-size: 12px; + overflow-x: auto; +} + +pre { + padding: 20px; + background: #3A3C42; + color: #f8f8f2; + margin: 0 -20px 20px; +} +pre code { + color: #f8f8f2; +} +li pre { + margin-left: -60px; + padding-left: 60px; +} + +table { + width: 100%; + border-collapse: collapse; +} + +th, td { + text-align: left; + padding: 5px 10px; + border-bottom: 1px solid #aaa; +} + +dt { + color: #222; + font-weight: 700; +} + +th { + color: #222; +} + +small { + font-size: 11px; +} + +hr { + border: 0; + background: #aaa; + height: 1px; + margin: 0 0 20px; +} + +footer { + width: 640px; + margin: 0 auto; + padding: 20px 0 0; + color: #ccc; + overflow: hidden; +} +footer a { + color: #fff; + font-weight: bold; +} +footer p { + float: left; +} +footer p + p { + float: right; +} + +@media print, screen and (max-width: 740px) { + body { + padding: 0; + } + + .wrapper { + -webkit-border-radius: 0; + -moz-border-radius: 0; + -ms-border-radius: 0; + -o-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + width: 100%; + } + + footer { + -webkit-border-radius: 0; + -moz-border-radius: 0; + -ms-border-radius: 0; + -o-border-radius: 0; + border-radius: 0; + padding: 20px; + width: auto; + } + footer p { + float: none; + margin: 0; + } + footer p + p { + float: none; + } +} +@media print, screen and (max-width:580px) { + header ul { + display: none; + } + + header p.view { + display: block; + } + + header p { + width: 100%; + } +} +@media print { + header p.view a small:before { + content: 'at http://github.com/'; + } +} From 4d4ea54385804f03ab56b969f5da8060a5926349 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Fri, 22 Feb 2013 16:24:51 -0800 Subject: [PATCH 02/19] Create gh-pages branch via GitHub --- index.html | 198 ++++++++++++++++------------------------------------ params.json | 2 +- 2 files changed, 63 insertions(+), 137 deletions(-) diff --git a/index.html b/index.html index 11471a9..67498b1 100644 --- a/index.html +++ b/index.html @@ -46,21 +46,17 @@

Basics

A simple example:

-
-
Contract Num, Num => Num
+
Contract Num, Num => Num
 def add(a, b)
    a + b
  end
-
-
- +

Here, the contract is Contract Num, Num => Num. This says that the add function takes two numbers and returns a number.

Copy this code into a file and run it:

-
-
require 'contracts'
+
require 'contracts'
 include Contracts
 
 Contract Num, Num => Num
@@ -69,9 +65,7 @@ 

Basics

end puts add(1, "foo") -
-
- +

You'll see a detailed error message like so:

@@ -86,13 +80,21 @@

Basics

That tells you that your contract was violated! add expected a Num, and got a string ("foo") instead. By default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.

+

You can also see the contract for a function with the functype method:

+ +
functype(:add)
+=> "add :: Num, Num => Num"
+
+ +

This can be useful if you're in a repl and want to figure out how a function should be used.

+

Builtin Contracts

Num is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the Contracts namespace. The easiest way to use them is to put include Contracts at the top of your file, but beware that they will pollute your namespace with new class names.

contracts.ruby comes with a lot of builtin contracts, including:

-
Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, IsA, ArrayOf
+
Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, IsA, ArrayOf, Bool, Maybe
 

To see all the builtin contracts and what they do, check out the rdoc.

@@ -101,14 +103,11 @@

More Examples

Hello, World

-
-
Contract String => nil
+
Contract String => nil
 def hello(name)
   puts "hello, #{name}!"
 end
-
-
- +

You always need to specify a contract for the return value. In this example, hello doesn't return anything, so the contract is nil. Now you know that you can use a constant like nil as the of a contract. Valid values for a contract are:

@@ -120,46 +119,33 @@

Hello, World

  • an instance of a class that responds to the valid? method (more on this later)
  • A Double Function

    -
    -
    Contract Or[Fixnum, Float] => Or[Fixnum, Float]
    +
    Contract Or[Fixnum, Float] => Or[Fixnum, Float]
     def double(x)
       2 * x
     end
    -
    -
    - +

    Sometimes you want to be able to choose between a few contracts. Or takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the Or contract passes. This introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the valid? method. This is what Or[Fixnum, Float] is. The longer way to write it would have been:

    -
    -
    Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
    -
    -
    - +
    Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
    +

    All the builtin contracts have overridden the square brackets ([]) to give the same functionality. So you could write

    -
    -
    Contract Or[Fixnum, Float] => Or[Fixnum, Float]
    -
    -
    - +
    Contract Or[Fixnum, Float] => Or[Fixnum, Float]
    +

    or

    -
    -
    Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
    -
    -
    - +
    Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
    +

    whichever you prefer. They both mean the same thing here: make a new instance of Or with Fixnum and Float. Use that instance to validate the argument.

    A Product Function

    -
    -
    Contract ArrayOf[Num] => Num
    +
    Contract ArrayOf[Num] => Num
     def product(vals)
       total = 1
       vals.each do |val|
    @@ -167,26 +153,20 @@ 

    A Product Function

    end total end -
    -
    - +

    This contract uses the ArrayOf contract. Here's how ArrayOf works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.

    -
    -
    # passes
    +
    # passes
     product([1, 2, 3, 4])
     
     # fails
     product([1, 2, 3, "foo"])
    -
    -
    - +

    Another Product Function

    -
    -
    Contract Args[Num] => Num
    +
    Contract Args[Num] => Num
     def product(*vals)
       total = 1
       vals.each do |val|
    @@ -194,9 +174,7 @@ 

    Another Product Function

    end total end -
    -
    - +

    This function uses varargs (*args) instead of an array. To make a contract on varargs, use the Args contract. It takes one contract as an argument and uses it to validate every element passed in through *args. So for example,

    @@ -210,15 +188,12 @@

    Contracts On Arrays

    If an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:

    -
    -
    # a function that takes an array of two elements...a person's age and a person's name.
    +
    # a function that takes an array of two elements...a person's age and a person's name.
     Contract [Num, String] => nil
     def person(data)
       p data
     end
    -
    -
    - +

    If you don't know how many elements it's going to have, use ArrayOf.

    @@ -226,33 +201,24 @@

    Contracts On Hashes

    Here's a contract that requires a Hash. We can put contracts on each of the keys:

    -
    -
    # note the parentheses around the hash; without those you would get a syntax error
    +
    # note the parentheses around the hash; without those you would get a syntax error
     Contract ({ :age => Num, :name => String }) => nil
     def person(data)
       p data
     end
    -
    -
    - +

    Then if someone tries to call the function with bad data, it will fail:

    -
    -
    # error: age can't be nil!
    +
    # error: age can't be nil!
     person({:name => "Adit", :age => nil})
    -
    -
    - +

    You don't need to put a contract on every key. So this call would succeed:

    -
    -
    # error: age can't be nil!
    +
    # error: age can't be nil!
     person({:name => "Adit", :age => nil, :foo => "bar"})
    -
    -
    - +

    even though we don't specify a type for :foo.

    @@ -263,8 +229,7 @@

    Contracts On Functions

    Here's a map function that requires an array of numbers, and a function that takes a number and returns a number:

    -
    -
    Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]
    +
    Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]
     def map(arr, func)
       ret = []
       arr.each do |x|
    @@ -272,55 +237,41 @@ 

    Contracts On Functions

    end ret end -
    -
    - +

    This will add the contract Num => Num on func. Try it with these two examples:

    -
    -
    p map([1, 2, 3], lambda { |x| x + 1 }) # works
    +
    p map([1, 2, 3], lambda { |x| x + 1 }) # works
     p map([1, 2, 3], lambda { |x| "oops" }) # fails, the lambda returns a string.
    -
    -
    - +

    Returning Multiple Values

    Treat the return value as an array. For example, here's a function that returns two numbers:

    -
    -
    Contract Num => [Num, Num]
    +
    Contract Num => [Num, Num]
     def mult(x)
       return x, x+1
     end
    -
    -
    - +

    Synonyms For Contracts

    If you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a Hash or nil. If a Hash is returned, it contains information about a person. Your contact might look like this:

    -
    -
    Contract String => Or[Hash, nil]
    +
    Contract String => Or[Hash, nil]
     def some_func(str)
    -
    -
    - +

    You can make your contract more meaningful with a synonym:

    -
    -
    # the synonym
    +
    # the synonym
     Person = Or[Hash, nil]
     
     # use the synonym here
     Contract String => Person
     def some_func(str)
    -
    -
    - +

    Now you can use Person wherever you would have used Or[Hash, nil]. Your code is now cleaner and more clearly says what the function is doing.

    @@ -338,12 +289,9 @@

    Defining Your Own Contracts

    A Proc

    -
    -
    Contract lambda { |x| x.is_a? Numeric } => Num
    +
    Contract lambda { |x| x.is_a? Numeric } => Num
     def double(x)
    -
    -
    - +

    The lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a Numeric. If it is, it returns true. Otherwise it returns false. It's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:

    @@ -352,15 +300,12 @@

    A Class With valid? As a Class Method

    Here's how the Num class is defined. It does exactly what the lambda did in the previous example:

    -
    -
    class Num
    +
    class Num
       def self.valid? val
         val.is_a? Numeric
       end
     end
    -
    -
    - +

    The valid? class method takes one parameter: the argument that is getting passed to the function. It returns true or false.

    @@ -368,8 +313,7 @@

    A Class With valid? As an Instance Method

    Here's how the Or class is defined:

    -
    -
    class Or < CallableClass
    +
    class Or < CallableClass
       def initialize(*vals)
         @vals = vals
       end
    @@ -381,32 +325,24 @@ 

    A Class With valid? As an Instance Method

    end end end -
    -
    - +

    The Or contract takes a sequence of contracts, and passes if any of them pass. It uses Contract.valid? to validate the value against the contracts.

    This class inherits from CallableClass, which allows us to use [] when using the class:

    -
    -
    Contract Or[Fixnum, Float] => Num
    +
    Contract Or[Fixnum, Float] => Num
     def double(x)
       2 * x
     end
    -
    -
    - +

    Without CallableClass, we would have to use .new instead:

    -
    -
    Contract Or.new(Fixnum, Float) => Num
    +
    Contract Or.new(Fixnum, Float) => Num
     def double(x)
     # etc
    -
    -
    - +

    You can use CallableClass in your own contracts to make them callable using [].

    @@ -421,13 +357,10 @@

    Customizing Error Messages

    You can customize this message by overriding the to_s method on your class or proc. For example, suppose we overrode Num's to_s method:

    -
    -
    def Num.to_s
    +
    def Num.to_s
       "a number please"
     end
    -
    -
    - +

    Now the error says:

    @@ -442,15 +375,12 @@

    Failure and Success Callbacks

    contracts.ruby provides a failure_callback that gets called when a contract fails. By monkeypatching failure_callback, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:

    -
    -
    class Contract
    +
    class Contract
       def self.failure_callback(data)
         info failure_msg(data)
       end
     end
    -
    -
    - +

    failure_msg is a function that prints out information about the failure. failure_callback takes a hash with the following values:

    @@ -467,10 +397,6 @@

    Failure and Success Callbacks

    If either callback returns false, the method that the contract is guarding will not be called.

    -

    Gotchas

    - -

    Contracts don't work on top level functions. Any function with a contract should be in a class.

    -

    Misc

    Please submit any bugs here and I'll try to get them resolved ASAP!

    @@ -486,7 +412,7 @@

    Misc

    Project maintained by egonSchiele

    Hosted on GitHub Pages — Theme by orderedlist

    - + diff --git a/params.json b/params.json index 311fbe8..fce4505 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\n end\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6 \r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, IsA, ArrayOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers. \r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf `failure_callback` returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-29851666-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\n end\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6 \r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers. \r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf `failure_callback` returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From dec62deab1519cf163e0e0d0b64cef989faa5db6 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Tue, 6 Jan 2015 15:57:14 -0800 Subject: [PATCH 08/19] Create gh-pages branch via GitHub --- images/checker.png | Bin 250 -> 108 bytes index.html | 367 +++++++++++++++++++++------------------------ params.json | 2 +- 3 files changed, 175 insertions(+), 194 deletions(-) diff --git a/images/checker.png b/images/checker.png index ab1454032c6ec47a4c974f4e4d75bd226911b4fc..7a65b2333db936d13c14599ba346697316e5c17a 100644 GIT binary patch delta 90 zcmeyxm@`2lgprwnfua0JUlx#J3-AeXeemFcUS!L^@9$E8B1|Pge!)^w)_2a$1oDJE qT^vIy7?X9<6A}{MGzd1ga5GG2;7`4FJ@gS!n!(f6&t;ucLK6T|HXauM literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^3P3E!!3HFKxnwkf6icy_X9x!n)NrJ90QsB+9+AZi z4BSE>%y{W;-5;Q!Oo?kmNpOBzNqJ&XDuZK6ep0G}TV_#ed45rLv4V53Y2nt#W z{&tJwQo64!`zEoY0VG=WX{H35gh8JhW7>iX;yrE$GemF_3=9!wFW${k`+fjuK7*&L KpUXO@geCwfrcS5; diff --git a/index.html b/index.html index 7de55ba..0179c1d 100644 --- a/index.html +++ b/index.html @@ -28,10 +28,10 @@

    Contracts.ruby

    -The contracts.ruby tutorial

    +The contracts.ruby tutorial

    -Introduction

    +Introduction

    contracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you

    @@ -39,37 +39,37 @@

  • catch bugs faster
  • make it very easy to catch certain types of bugs
  • make sure that the user gets proper messaging when a bug occurs.
  • -

    -Installation

    + + +

    +Installation

    gem install contracts
     

    -Basics

    +Basics

    A simple example:

    -
    Contract Num, Num => Num
    -def add(a, b)
    -   a + b
    - end
    -
    +
    Contract Num, Num => Num
    +def add(a, b)
    +  a + b
    +end

    Here, the contract is Contract Num, Num => Num. This says that the add function takes two numbers and returns a number.

    Copy this code into a file and run it:

    -
    require 'contracts'
    -include Contracts
    +
    require 'contracts'
    +include Contracts
     
    -Contract Num, Num => Num
    -def add(a, b)
    -   a + b
    -end
    +Contract Num, Num => Num
    +def add(a, b)
    +  a + b
    +end
     
    -puts add(1, "foo")
    -
    +puts add(1, "foo")

    You'll see a detailed error message like so:

    @@ -78,7 +78,7 @@

    Actual: "foo" Value guarded in: Object::add With Contract: Contracts::Num, Contracts::Num - At: foo.rb:6 + At: foo.rb:6

    That tells you that your contract was violated! add expected a Num, and got a string ("foo") instead. @@ -93,7 +93,7 @@

    This can be useful if you're in a repl and want to figure out how a function should be used.

    -Builtin Contracts

    +Builtin Contracts

    Num is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the Contracts namespace. The easiest way to use them is to put include Contracts at the top of your file, but beware that they will pollute your namespace with new class names.

    @@ -105,16 +105,15 @@

    To see all the builtin contracts and what they do, check out the rdoc.

    -More Examples

    +More Examples

    -Hello, World

    +Hello, World -
    Contract String => nil
    -def hello(name)
    -  puts "hello, #{name}!"
    -end
    -
    +
    Contract String => nil
    +def hello(name)
    +  puts "hello, #{name}!"
    +end

    You always need to specify a contract for the return value. In this example, hello doesn't return anything, so the contract is nil. Now you know that you can use a constant like nil as the of a contract. Valid values for a contract are:

    @@ -124,190 +123,174 @@

  • a Proc that takes a value and returns true or false to indicate whether the contract passed or not
  • a class that responds to the valid? class method (more on this later)
  • an instance of a class that responds to the valid? method (more on this later)
  • -

    -A Double Function

    + -
    Contract Or[Fixnum, Float] => Or[Fixnum, Float]
    -def double(x)
    -  2 * x
    -end
    -
    +

    +A Double Function

    + +
    Contract Or[Fixnum, Float] => Or[Fixnum, Float]
    +def double(x)
    +  2 * x
    +end

    Sometimes you want to be able to choose between a few contracts. Or takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the Or contract passes. This introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the valid? method. This is what Or[Fixnum, Float] is. The longer way to write it would have been:

    -
    Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
    -
    +
    Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)

    All the builtin contracts have overridden the square brackets ([]) to give the same functionality. So you could write

    -
    Contract Or[Fixnum, Float] => Or[Fixnum, Float]
    -
    +
    Contract Or[Fixnum, Float] => Or[Fixnum, Float]

    or

    -
    Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
    -
    +
    Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)

    whichever you prefer. They both mean the same thing here: make a new instance of Or with Fixnum and Float. Use that instance to validate the argument.

    -A Product Function

    - -
    Contract ArrayOf[Num] => Num
    -def product(vals)
    -  total = 1
    -  vals.each do |val|
    -    total *= val
    -  end
    -  total
    -end
    -
    +A Product Function + +
    Contract ArrayOf[Num] => Num
    +def product(vals)
    +  total = 1
    +  vals.each do |val|
    +    total *= val
    +  end
    +  total
    +end

    This contract uses the ArrayOf contract. Here's how ArrayOf works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.

    -
    # passes
    -product([1, 2, 3, 4])
    +
    # passes
    +product([1, 2, 3, 4])
     
    -# fails
    -product([1, 2, 3, "foo"])
    -
    +# fails +product([1, 2, 3, "foo"])

    -Another Product Function

    - -
    Contract Args[Num] => Num
    -def product(*vals)
    -  total = 1
    -  vals.each do |val|
    -    total *= val
    -  end
    -  total
    -end
    -
    +Another Product Function + +
    Contract Args[Num] => Num
    +def product(*vals)
    +  total = 1
    +  vals.each do |val|
    +    total *= val
    +  end
    +  total
    +end

    This function uses varargs (*args) instead of an array. To make a contract on varargs, use the Args contract. It takes one contract as an argument and uses it to validate every element passed in through *args. So for example,

    -

    Args[Num] means they should all be numbers.

    +

    Args[Num] means they should all be numbers.

    Args[Or[Num, String]] means they should all be numbers or strings.

    Args[Any] means all arguments are allowed (Any is a contract that passes for any argument).

    -Contracts On Arrays

    +Contracts On Arrays

    If an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:

    -
    # a function that takes an array of two elements...a person's age and a person's name.
    -Contract [Num, String] => nil
    -def person(data)
    -  p data
    -end
    -
    +
    # a function that takes an array of two elements...a person's age and a person's name.
    +Contract [Num, String] => nil
    +def person(data)
    +  p data
    +end

    If you don't know how many elements it's going to have, use ArrayOf.

    -Contracts On Hashes

    +Contracts On Hashes

    Here's a contract that requires a Hash. We can put contracts on each of the keys:

    -
    # note the parentheses around the hash; without those you would get a syntax error
    -Contract ({ :age => Num, :name => String }) => nil
    -def person(data)
    -  p data
    -end
    -
    +
    # note the parentheses around the hash; without those you would get a syntax error
    +Contract ({ :age => Num, :name => String }) => nil
    +def person(data)
    +  p data
    +end

    Then if someone tries to call the function with bad data, it will fail:

    -
    # error: age can't be nil!
    -person({:name => "Adit", :age => nil})
    -
    +
    # error: age can't be nil!
    +person({:name => "Adit", :age => nil})

    You don't need to put a contract on every key. So this call would succeed:

    -
    person({:name => "Adit", :age => 42, :foo => "bar"})
    -
    +
    person({:name => "Adit", :age => 42, :foo => "bar"})

    even though we don't specify a type for :foo.

    Peruse this contract on the keys and values of a Hash.

    -
    Contract HashOf[Symbol, Num] => Num
    -def give_largest_value(hsh)
    -  hsh.values.max
    -end
    -
    +
    Contract HashOf[Symbol, Num] => Num
    +def give_largest_value(hsh)
    +  hsh.values.max
    +end

    Which you use like so:

    -
    # succeeds
    -give_largest_value(a: 1, b: 2, c: 3) # returns 3
    +
    # succeeds
    +give_largest_value(a: 1, b: 2, c: 3) # returns 3
     
    -# fails
    -give_largest_value("a" => 1, 2 => 2, c: 3)
    -
    +# fails +give_largest_value("a" => 1, 2 => 2, c: 3)

    -Contracts On Functions

    +Contracts On Functions

    If you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can! Use the Func contract. Func takes a contract as it's argument, and uses that contract on the function that you pass in.

    Here's a map function that requires an array of numbers, and a function that takes a number and returns a number:

    -
    Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]
    -def map(arr, func)
    -  ret = []
    -  arr.each do |x|
    -    ret << func[x]
    -  end
    -  ret
    -end
    -
    +
    Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]
    +def map(arr, func)
    +  ret = []
    +  arr.each do |x|
    +    ret << func[x]
    +  end
    +  ret
    +end

    This will add the contract Num => Num on func. Try it with these two examples:

    -
    p map([1, 2, 3], lambda { |x| x + 1 }) # works
    -p map([1, 2, 3], lambda { |x| "oops" }) # fails, the lambda returns a string.
    -
    +
    p map([1, 2, 3], lambda { |x| x + 1 }) # works
    +p map([1, 2, 3], lambda { |x| "oops" }) # fails, the lambda returns a string.

    -Returning Multiple Values

    +Returning Multiple Values

    Treat the return value as an array. For example, here's a function that returns two numbers:

    -
    Contract Num => [Num, Num]
    -def mult(x)
    -  return x, x+1
    -end
    -
    +
    Contract Num => [Num, Num]
    +def mult(x)
    +  return x, x+1
    +end

    -Synonyms For Contracts

    +Synonyms For Contracts

    If you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a Hash or nil. If a Hash is returned, it contains information about a person. Your contact might look like this:

    -
    Contract String => Or[Hash, nil]
    -def some_func(str)
    -
    +
    Contract String => Or[Hash, nil]
    +def some_func(str)

    You can make your contract more meaningful with a synonym:

    -
    # the synonym
    -Person = Or[Hash, nil]
    +
    # the synonym
    +Person = Or[Hash, nil]
     
    -# use the synonym here
    -Contract String => Person
    -def some_func(str)
    -
    +# use the synonym here +Contract String => Person +def some_func(str)

    Now you can use Person wherever you would have used Or[Hash, nil]. Your code is now cleaner and more clearly says what the function is doing.

    -Defining Your Own Contracts

    +Defining Your Own Contracts

    Contracts are very easy to define. To re-iterate, there are 5 kinds of contracts:

    @@ -317,72 +300,69 @@

  • a Proc that takes a value and returns true or false to indicate whether the contract passed or not
  • a class that responds to the valid? class method (more on this later)
  • an instance of a class that responds to the valid? method (more on this later)
  • -

    The first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:

    + + +

    The first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:

    -A Proc

    +A Proc -
    Contract lambda { |x| x.is_a? Numeric } => Num
    -def double(x)
    -
    +
    Contract lambda { |x| x.is_a? Numeric } => Num
    +def double(x)

    The lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a Numeric. If it is, it returns true. Otherwise it returns false. It's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:

    -A Class With valid? As a Class Method

    +A Class With valid? As a Class Method

    Here's how the Num class is defined. It does exactly what the lambda did in the previous example:

    -
    class Num
    -  def self.valid? val
    -    val.is_a? Numeric
    -  end
    -end
    -
    +
    class Num
    +  def self.valid? val
    +    val.is_a? Numeric
    +  end
    +end

    The valid? class method takes one parameter: the argument that is getting passed to the function. It returns true or false.

    -A Class With valid? As an Instance Method

    +A Class With valid? As an Instance Method

    Here's how the Or class is defined:

    -
    class Or < CallableClass
    -  def initialize(*vals)
    -    @vals = vals
    -  end
    +
    class Or < CallableClass
    +  def initialize(*vals)
    +    @vals = vals
    +  end
     
    -  def valid?(val)
    -    @vals.any? do |contract|
    -      res, _ = Contract.valid?(val, contract)
    -      res
    -    end
    -  end
    -end
    -
    + def valid?(val) + @vals.any? do |contract| + res, _ = Contract.valid?(val, contract) + res + end + end +end

    The Or contract takes a sequence of contracts, and passes if any of them pass. It uses Contract.valid? to validate the value against the contracts.

    This class inherits from CallableClass, which allows us to use [] when using the class:

    -
    Contract Or[Fixnum, Float] => Num
    -def double(x)
    -  2 * x
    -end
    -
    +
    Contract Or[Fixnum, Float] => Num
    +def double(x)
    +  2 * x
    +end

    Without CallableClass, we would have to use .new instead:

    -
    Contract Or.new(Fixnum, Float) => Num
    -def double(x)
    -# etc
    -
    +
    Contract Or.new(Fixnum, Float) => Num
    +def double(x)
    +# etc

    You can use CallableClass in your own contracts to make them callable using [].

    -Customizing Error Messages

    +Customizing Error Messages

    When a contract fails, part of the error message prints the contract:

    @@ -393,10 +373,9 @@

    You can customize this message by overriding the to_s method on your class or proc. For example, suppose we overrode Num's to_s method:

    -
    def Num.to_s
    -  "a number please"
    -end
    -
    +
    def Num.to_s
    +  "a number please"
    +end

    Now the error says:

    @@ -406,18 +385,17 @@

    -Failure Callbacks

    +Failure Callbacks

    Supposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.

    contracts.ruby provides a failure_callback that gets called when a contract fails. By monkeypatching failure_callback, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:

    -
    class Contract
    -  def self.failure_callback(data)
    -    info failure_msg(data)
    -  end
    -end
    -
    +
    class Contract
    +  def self.failure_callback(data)
    +    info failure_msg(data)
    +  end
    +end

    failure_msg is a function that prints out information about the failure. failure_callback takes a hash with the following values:

    @@ -433,37 +411,40 @@

    If failure_callback returns false, the method that the contract is guarding will not be called (the default behaviour).

    -Method overloading

    +Disabling contracts + +

    If you want to disable contracts, set the NO_CONTRACTS environment variable. This will disable contracts completely.

    + +

    +Method overloading

    You can use contracts for method overloading! For example, here's a factorial function without method overloading:

    -
    Contract Num => Num
    -def fact x
    -  if x == 1
    -    x
    -  else
    -    x * fact(x - 1)
    -  end
    -end
    -
    +
    Contract Num => Num
    +def fact x
    +  if x == 1
    +    x
    +  else
    +    x * fact(x - 1)
    +  end
    +end

    Here it is again, re-written with method overloading:

    -
    Contract 1 => 1
    -def fact x
    -  x
    -end
    +
    Contract 1 => 1
    +def fact x
    +  x
    +end
     
    -Contract Num => Num
    -def fact x
    -  x * fact(x - 1)
    -end
    -
    +Contract Num => Num +def fact x + x * fact(x - 1) +end

    For an argument, each function will be tried in order. The first function that doesn't raise a ContractError will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.

    -Misc

    +Misc

    Please submit any bugs here and I'll try to get them resolved ASAP!

    diff --git a/params.json b/params.json index fce4505..75084e7 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\n end\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6 \r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers. \r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf `failure_callback` returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf `failure_callback` returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From ca48f0843eb526313f4bdcb213167df238b40543 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Fri, 9 Jan 2015 10:53:25 -0800 Subject: [PATCH 09/19] Create gh-pages branch via GitHub --- index.html | 2 +- params.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 0179c1d..a3c9ec8 100644 --- a/index.html +++ b/index.html @@ -115,7 +115,7 @@

    puts "hello, #{name}!" end -

    You always need to specify a contract for the return value. In this example, hello doesn't return anything, so the contract is nil. Now you know that you can use a constant like nil as the of a contract. Valid values for a contract are:

    +

    You always need to specify a contract for the return value. In this example, hello doesn't return anything, so the contract is nil. Now you know that you can use a constant like nil as the end of a contract. Valid values for a contract are:

    • the name of a class (like String or Fixnum)
    • diff --git a/params.json b/params.json index 75084e7..cdf6103 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf `failure_callback` returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf `failure_callback` returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 6646f7e3ea560f9ea7939c16259ab4c9ac09df1c Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Tue, 13 Jan 2015 10:28:38 -0800 Subject: [PATCH 10/19] Create gh-pages branch via GitHub --- index.html | 35 +++++++++++++++++++++++++++++++++++ params.json | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index a3c9ec8..172564d 100644 --- a/index.html +++ b/index.html @@ -443,6 +443,41 @@

      For an argument, each function will be tried in order. The first function that doesn't raise a ContractError will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.

      +

      +Invariants

      + +

      Invariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.

      + +

      NOTE: Only methods with contracts will be affected.

      + +

      A simple example:

      + +
      class MyBirthday < Struct.new(:day, :month)
      +  include Contracts
      +  include Contracts:Invariants
      +
      +  Invariant(:day) { 1 <= day && day <= 31 }
      +  Invariant(:month) { 1 <= month && month <= 12 }
      +
      +  Contract None => Fixnum
      +  def silly_next_day!
      +    self.day += 1
      +  end
      +end
      +
      +birthday = MyBirthday.new(31, 12)
      +birthday.silly_next_day!
      + +

      If you run it, last line will generate invariant violation:

      + +
      ./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)
      +   Expected: day condition to be true
      +   Actual: false
      +   Value guarded in: MyBirthday::silly_next_day!
      +   At: main.rb:9
      + +

      Which means, that after #silly_next_day! all checks specified in Invariant statement will be verified, and if at least one fail, then Invariant violation error will be raised.

      +

      Misc

      diff --git a/params.json b/params.json index cdf6103..38cc923 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf `failure_callback` returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf `failure_callback` returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts:Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!\r\n","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From ba9a4e8342c2d4ff17c41ab7363f5ef3efface7d Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Tue, 13 Jan 2015 16:16:16 -0800 Subject: [PATCH 11/19] Create gh-pages branch via GitHub --- index.html | 15 +++++++-------- params.json | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 172564d..c879e61 100644 --- a/index.html +++ b/index.html @@ -389,15 +389,14 @@

      Supposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.

      -

      contracts.ruby provides a failure_callback that gets called when a contract fails. By monkeypatching failure_callback, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:

      +

      contracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:

      -
      class Contract
      -  def self.failure_callback(data)
      -    info failure_msg(data)
      -  end
      +
      Contract.override_failure_callback do |data|
      +  puts "You had an error"
      +  puts failure_msg(data)
       end
      -

      failure_msg is a function that prints out information about the failure. failure_callback takes a hash with the following values:

      +

      failure_msg is a function that prints out information about the failure. Your failure callback gets a hash with the following values:

      {
         :arg => the argument to the method,
      @@ -408,12 +407,12 @@ 

      }

      -

      If failure_callback returns false, the method that the contract is guarding will not be called (the default behaviour).

      +

      If your failure callback returns false, the method that the contract is guarding will not be called (the default behaviour).

      Disabling contracts

      -

      If you want to disable contracts, set the NO_CONTRACTS environment variable. This will disable contracts completely.

      +

      If you want to disable contracts, set the NO_CONTRACTS environment variable. This will disable contracts completely and you won't have a performance hit.

      Method overloading

      diff --git a/params.json b/params.json index 38cc923..604f072 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a `failure_callback` that gets called when a contract fails. By monkeypatching `failure_callback`, you can customize the behavior of contracts.ruby. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nclass Contract\r\n def self.failure_callback(data)\r\n info failure_msg(data)\r\n end\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. `failure_callback` takes a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf `failure_callback` returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts:Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!\r\n","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely and you won't have a performance hit.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts:Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 3b83f101a4b0e13ea5fb6b695cc62cee1df124ab Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Tue, 20 Jan 2015 13:16:44 -0800 Subject: [PATCH 12/19] Create gh-pages branch via GitHub --- index.html | 14 ++++++++++++++ params.json | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index c879e61..38f0555 100644 --- a/index.html +++ b/index.html @@ -442,6 +442,20 @@

      For an argument, each function will be tried in order. The first function that doesn't raise a ContractError will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.

      +

      +Contracts in modules

      + +

      To use contracts on module you need to include both Contracts and Contracts::Modules into it:

      + +
      module M
      +  include Contracts
      +  include Contracts::Modules
      +
      +  Contract String => String
      +  def self.parse
      +    # do some hard parsing
      +  end
      +

      Invariants

      diff --git a/params.json b/params.json index 604f072..ba9e36b 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely and you won't have a performance hit.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts:Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely and you won't have a performance hit.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n include Contracts\r\n include Contracts::Modules\r\n\r\n Contract String => String\r\n def self.parse\r\n # do some hard parsing\r\n end\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts:Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 90163bc3335c191264844c29762bb13834e85583 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Wed, 4 Feb 2015 18:18:55 -0800 Subject: [PATCH 13/19] Create gh-pages branch via GitHub From c1c1a1aba7262be2ea41bf1d36a7bc33ac9558e5 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Sun, 8 Mar 2015 14:57:38 -0700 Subject: [PATCH 14/19] Create gh-pages branch via GitHub --- index.html | 72 +++++++++++++++++++++++++++++++++++++++++++---------- params.json | 2 +- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/index.html b/index.html index 38f0555..9a741f1 100644 --- a/index.html +++ b/index.html @@ -62,14 +62,17 @@

      Copy this code into a file and run it:

      require 'contracts'
      -include Contracts
       
      -Contract Num, Num => Num
      -def add(a, b)
      -  a + b
      +class Math
      +  include Contracts
      +
      +  Contract Num, Num => Num
      +  def self.add(a, b)
      +    a + b
      +  end
       end
       
      -puts add(1, "foo")
      +puts Math.add(1, "foo")

      You'll see a detailed error message like so:

      @@ -95,7 +98,7 @@

      Builtin Contracts

      -

      Num is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the Contracts namespace. The easiest way to use them is to put include Contracts at the top of your file, but beware that they will pollute your namespace with new class names.

      +

      Num is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the Contracts namespace. The easiest way to use them is to include the Contracts module in your class/module.

      contracts.ruby comes with a lot of builtin contracts, including:

      @@ -241,8 +244,20 @@

      Contracts On Functions

      -

      If you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can! -Use the Func contract. Func takes a contract as it's argument, and uses that contract on the function that you pass in.

      +

      Lets say you are writing a simple map function:

      + +
      def map(arr, func)
      + +

      map takes an array, and a function. Suppose you want to add a contract to this function. You could try this:

      + +
      Contract ArrayOf[Any], Proc => ArrayOf[Any]
      +def map(arr, func)
      + +

      This says that the second argument should be a Proc. You can call the function like so:

      + +
      p map([1, 2, 3], lambda { |x| x + 1 }) # works
      + +

      But suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the Func contract. Func takes a contract as it's argument, and uses that contract on the function that you pass in.

      Here's a map function that requires an array of numbers, and a function that takes a number and returns a number:

      @@ -255,11 +270,20 @@

      ret end -

      This will add the contract Num => Num on func. Try it with these two examples:

      +

      Earlier, we used Proc, which just says "make sure the second variable is a Proc". Now we are using Func[Num => Num], which says "make sure the second variable is a Proc that takes a number and returns a number". Better!

      + +

      Try this map function with these two examples:

      p map([1, 2, 3], lambda { |x| x + 1 }) # works
       p map([1, 2, 3], lambda { |x| "oops" }) # fails, the lambda returns a string.
      +

      NOTE: This is not valid:

      + +
      Contract ArrayOf[Num], Func => ArrayOf[Num]
      +def map(arr, &func)
      + +

      Here I am using Func without specifying a contract, like Func[Num => Num]. That's not a legal contract. If you just want to validate that the second argument is a proc, use Proc.

      +

      Returning Multiple Values

      @@ -412,12 +436,14 @@

      Disabling contracts

      -

      If you want to disable contracts, set the NO_CONTRACTS environment variable. This will disable contracts completely and you won't have a performance hit.

      +

      If you want to disable contracts, set the NO_CONTRACTS environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.

      Method overloading

      -

      You can use contracts for method overloading! For example, here's a factorial function without method overloading:

      +

      You can use contracts for method overloading! This is commonly called "pattern matching" in functional programming languages.

      + +

      For example, here's a factorial function without method overloading:

      Contract Num => Num
       def fact x
      @@ -442,6 +468,25 @@ 

      For an argument, each function will be tried in order. The first function that doesn't raise a ContractError will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.

      +

      This allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:

      + +
      Contract lambda{|n| n < 12 } => Ticket
      +def get_ticket(age)
      +  ChildTicket.new(age: age)
      +end
      +
      +Contract lambda{|n| n >= 12 } => Ticket
      +def get_ticket(age)
      +  AdultTicket.new(age: age)
      +end
      +
      + +

      Note that the second get_ticket contract above could have been simplified to:

      + +
      Contract Num => Ticket
      + +

      This is because the first contract eliminated the possibility of age being less than 12. However, the simpler contract is less explicit; you may want to "spell out" the age condition for clarity, especially if the method is overloaded with many contracts.

      +

      Contracts in modules

      @@ -454,7 +499,8 @@

      Contract String => String def self.parse # do some hard parsing - end

      + end +end

      Invariants

      @@ -467,7 +513,7 @@

      class MyBirthday < Struct.new(:day, :month)
         include Contracts
      -  include Contracts:Invariants
      +  include Contracts::Invariants
       
         Invariant(:day) { 1 <= day && day <= 31 }
         Invariant(:month) { 1 <= month && month <= 12 }
      diff --git a/params.json b/params.json
      index ba9e36b..6260d47 100644
      --- a/params.json
      +++ b/params.json
      @@ -1 +1 @@
      -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n    gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n  a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\ninclude Contracts\r\n\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n  a + b\r\nend\r\n\r\nputs add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n    ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n        Expected: Contracts::Num,\r\n        Actual: \"foo\"\r\n        Value guarded in: Object::add\r\n        With Contract: Contracts::Num, Contracts::Num\r\n        At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n    functype(:add)\r\n    => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n    Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n  puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n  2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n  total = 1\r\n  vals.each do |val|\r\n    total *= val\r\n  end\r\n  total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n  total = 1\r\n  vals.each do |val|\r\n    total *= val\r\n  end\r\n  total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n  p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n  p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n  hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nIf you're writing higher-order functions (functions that take functions as parameters) and want to write a contract for the passed-in function, you can!\r\nUse the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n  ret = []\r\n  arr.each do |x|\r\n    ret << func[x]\r\n  end\r\n  ret\r\nend\r\n```\r\n\r\nThis will add the contract `Num => Num` on `func`. Try it with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n  return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n  def self.valid? val\r\n    val.is_a? Numeric\r\n  end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n  def initialize(*vals)\r\n    @vals = vals\r\n  end\r\n\r\n  def valid?(val)\r\n    @vals.any? do |contract|\r\n      res, _ = Contract.valid?(val, contract)\r\n      res\r\n    end\r\n  end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n  2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n    ...\r\n    Expected: Contracts::Num,\r\n    ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n  \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n    ...\r\n    Expected: a number please,\r\n    ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n  puts \"You had an error\"\r\n  puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n    {\r\n      :arg => the argument to the method,\r\n      :contract => the contract that got violated,\r\n      :class => the method's class,\r\n      :method => the method,\r\n      :contracts => the contract object\r\n    }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely and you won't have a performance hit.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! For example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n  if x == 1\r\n    x\r\n  else\r\n    x * fact(x - 1)\r\n  end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n  x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n  x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n  include Contracts\r\n  include Contracts::Modules\r\n\r\n  Contract String => String\r\n  def self.parse\r\n    # do some hard parsing\r\n  end\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n  include Contracts\r\n  include Contracts:Invariants\r\n\r\n  Invariant(:day) { 1 <= day && day <= 31 }\r\n  Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n  Contract None => Fixnum\r\n  def silly_next_day!\r\n    self.day += 1\r\n  end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n   Expected: day condition to be true\r\n   Actual: false\r\n   Value guarded in: MyBirthday::silly_next_day!\r\n   At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."}
      \ No newline at end of file
      +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n    gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n  a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\n\r\nclass Math\r\n  include Contracts\r\n\r\n  Contract Num, Num => Num\r\n  def self.add(a, b)\r\n    a + b\r\n  end\r\nend\r\n\r\nputs Math.add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n    ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n        Expected: Contracts::Num,\r\n        Actual: \"foo\"\r\n        Value guarded in: Object::add\r\n        With Contract: Contracts::Num, Contracts::Num\r\n        At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n    functype(:add)\r\n    => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts` module in your class/module.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n    Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n  puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n  2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n  total = 1\r\n  vals.each do |val|\r\n    total *= val\r\n  end\r\n  total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n  total = 1\r\n  vals.each do |val|\r\n    total *= val\r\n  end\r\n  total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n  p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n  p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n  hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nLets say you are writing a simple map function:\r\n\r\n```ruby\r\ndef map(arr, func)\r\n```\r\n\r\n`map` takes an array, and a function. Suppose you want to add a contract to this function. You could try this:\r\n\r\n```ruby\r\nContract ArrayOf[Any], Proc => ArrayOf[Any]\r\ndef map(arr, func)\r\n```\r\n\r\nThis says that the second argument should be a `Proc`. You can call the function like so:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\n```\r\n\r\nBut suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n  ret = []\r\n  arr.each do |x|\r\n    ret << func[x]\r\n  end\r\n  ret\r\nend\r\n```\r\n\r\nEarlier, we used `Proc`, which just says \"make sure the second variable is a Proc\". Now we are using `Func[Num => Num]`, which says \"make sure the second variable is a Proc that takes a number and returns a number\". Better!\r\n\r\nTry this map function with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\nNOTE: This is not valid:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func => ArrayOf[Num]\r\ndef map(arr, &func)\r\n```\r\n\r\nHere I am using `Func` without specifying a contract, like `Func[Num => Num]`. That's not a legal contract. If you just want to validate that the second argument is a proc, use `Proc`.\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n  return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n  def self.valid? val\r\n    val.is_a? Numeric\r\n  end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n  def initialize(*vals)\r\n    @vals = vals\r\n  end\r\n\r\n  def valid?(val)\r\n    @vals.any? do |contract|\r\n      res, _ = Contract.valid?(val, contract)\r\n      res\r\n    end\r\n  end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n  2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n    ...\r\n    Expected: Contracts::Num,\r\n    ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n  \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n    ...\r\n    Expected: a number please,\r\n    ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n  puts \"You had an error\"\r\n  puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n    {\r\n      :arg => the argument to the method,\r\n      :contract => the contract that got violated,\r\n      :class => the method's class,\r\n      :method => the method,\r\n      :contracts => the contract object\r\n    }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! This is commonly called \"pattern matching\" in functional programming languages.\r\n\r\nFor example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n  if x == 1\r\n    x\r\n  else\r\n    x * fact(x - 1)\r\n  end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n  x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n  x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\nThis allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:\r\n\r\n```ruby\r\nContract lambda{|n| n < 12 } => Ticket\r\ndef get_ticket(age)\r\n  ChildTicket.new(age: age)\r\nend\r\n\r\nContract lambda{|n| n >= 12 } => Ticket\r\ndef get_ticket(age)\r\n  AdultTicket.new(age: age)\r\nend\r\n\r\n```\r\n\r\nNote that the second `get_ticket` contract above could have been simplified to:\r\n\r\n```ruby\r\nContract Num => Ticket\r\n```\r\n\r\nThis is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to \"spell out\" the age condition for clarity, especially if the method is overloaded with many contracts.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n  include Contracts\r\n  include Contracts::Modules\r\n\r\n  Contract String => String\r\n  def self.parse\r\n    # do some hard parsing\r\n  end\r\nend\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n  include Contracts\r\n  include Contracts::Invariants\r\n\r\n  Invariant(:day) { 1 <= day && day <= 31 }\r\n  Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n  Contract None => Fixnum\r\n  def silly_next_day!\r\n    self.day += 1\r\n  end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n   Expected: day condition to be true\r\n   Actual: false\r\n   Value guarded in: MyBirthday::silly_next_day!\r\n   At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."}
      \ No newline at end of file
      
      From 27be46474fa65f2c0ca955cf4965cdbf5dff3847 Mon Sep 17 00:00:00 2001
      From: Aditya Bhargava 
      Date: Mon, 9 Mar 2015 08:34:41 -0700
      Subject: [PATCH 15/19] Create gh-pages branch via GitHub
      
      ---
       index.html  | 58 +++++++++++++++++++++++++++++++++++++++++++++--------
       params.json |  2 +-
       2 files changed, 51 insertions(+), 9 deletions(-)
      
      diff --git a/index.html b/index.html
      index 9a741f1..93dc96e 100644
      --- a/index.html
      +++ b/index.html
      @@ -93,19 +93,61 @@ 

      => "add :: Num, Num => Num"

      -

      This can be useful if you're in a repl and want to figure out how a function should be used.

      +

      This can be useful if you're in a REPL and want to figure out how a function should be used.

      -Builtin Contracts

      +Built-in Contracts

      -

      Num is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the Contracts namespace. The easiest way to use them is to include the Contracts module in your class/module.

      +

      Num is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the Contracts namespace. The easiest way to use them is to include the Contracts module in your class/module.

      -

      contracts.ruby comes with a lot of builtin contracts, including:

      +

      contracts.ruby comes with a lot of built-in contracts, including the following:

      -
      Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe
      -
      +
        +
      • +Num – checks that the argument is Numeric +
      • +
      • +Pos – checks that the argument is a positive number
      • +
      • +Neg – checks that the argument is a negative number
      • +
      • +Bool – checks that the argument is true or false +
      • +
      • +Any – Passes for any argument. Use when the argument has no constraints.
      • +
      • +None – Fails for any argument. Use when the method takes no arguments.
      • +
      • +Or – passes if any of the given contracts pass, e.g. Or[Fixnum, Float] +
      • +
      • +Xor – passes if exactly one of the given contracts pass, e.g. Xor[Fixnum, Float] +
      • +
      • +And – passes if all contracts pass, e.g. And[Fixnum, Float] +
      • +
      • +Not – passes if all contracts fail for the given argument, e.g. Not[nil] +
      • +
      • +ArrayOf – checks that the argument is an array, and all elements pass the given contract, e.g. ArrayOf[Num] +
      • +
      • +HashOf – checks that the argument is a hash, and all keys and values pass the given contract, e.g. HashOf[Symbol, String] +
      • +
      • +Maybe – passes if the argument is nil, or if the given contract passes
      • +
      • +RespondTo – checks that the argument responds to all of the given methods, e.g. RespondTo[:password, :credit_card] +
      • +
      • +Send – checks that all named methods return true, e.g. Send[:valid?] +
      • +
      • +Exactly – checks that the argument has the given type, not accepting sub-classes, e.g. Exactly[Numeric].
      • +
      -

      To see all the builtin contracts and what they do, check out the rdoc.

      +

      To see all the built-in contracts and their full descriptions, check out the RDoc.

      More Examples

      @@ -141,7 +183,7 @@

      Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
      -

      All the builtin contracts have overridden the square brackets ([]) to give the same functionality. So you could write

      +

      All the built-in contracts have overridden the square brackets ([]) to give the same functionality. So you could write

      Contract Or[Fixnum, Float] => Or[Fixnum, Float]
      diff --git a/params.json b/params.json index 6260d47..5594fbb 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\n\r\nclass Math\r\n include Contracts\r\n\r\n Contract Num, Num => Num\r\n def self.add(a, b)\r\n a + b\r\n end\r\nend\r\n\r\nputs Math.add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a repl and want to figure out how a function should be used.\r\n\r\n## Builtin Contracts\r\n\r\n`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts` module in your class/module.\r\n\r\ncontracts.ruby comes with a lot of builtin contracts, including:\r\n\r\n Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe\r\n\r\nTo see all the builtin contracts and what they do, check out the [rdoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the builtin contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nLets say you are writing a simple map function:\r\n\r\n```ruby\r\ndef map(arr, func)\r\n```\r\n\r\n`map` takes an array, and a function. Suppose you want to add a contract to this function. You could try this:\r\n\r\n```ruby\r\nContract ArrayOf[Any], Proc => ArrayOf[Any]\r\ndef map(arr, func)\r\n```\r\n\r\nThis says that the second argument should be a `Proc`. You can call the function like so:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\n```\r\n\r\nBut suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nEarlier, we used `Proc`, which just says \"make sure the second variable is a Proc\". Now we are using `Func[Num => Num]`, which says \"make sure the second variable is a Proc that takes a number and returns a number\". Better!\r\n\r\nTry this map function with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\nNOTE: This is not valid:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func => ArrayOf[Num]\r\ndef map(arr, &func)\r\n```\r\n\r\nHere I am using `Func` without specifying a contract, like `Func[Num => Num]`. That's not a legal contract. If you just want to validate that the second argument is a proc, use `Proc`.\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! This is commonly called \"pattern matching\" in functional programming languages.\r\n\r\nFor example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\nThis allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:\r\n\r\n```ruby\r\nContract lambda{|n| n < 12 } => Ticket\r\ndef get_ticket(age)\r\n ChildTicket.new(age: age)\r\nend\r\n\r\nContract lambda{|n| n >= 12 } => Ticket\r\ndef get_ticket(age)\r\n AdultTicket.new(age: age)\r\nend\r\n\r\n```\r\n\r\nNote that the second `get_ticket` contract above could have been simplified to:\r\n\r\n```ruby\r\nContract Num => Ticket\r\n```\r\n\r\nThis is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to \"spell out\" the age condition for clarity, especially if the method is overloaded with many contracts.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n include Contracts\r\n include Contracts::Modules\r\n\r\n Contract String => String\r\n def self.parse\r\n # do some hard parsing\r\n end\r\nend\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts::Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\n\r\nclass Math\r\n include Contracts\r\n\r\n Contract Num, Num => Num\r\n def self.add(a, b)\r\n a + b\r\n end\r\nend\r\n\r\nputs Math.add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a REPL and want to figure out how a function should be used.\r\n\r\n## Built-in Contracts\r\n\r\n`Num` is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts` module in your class/module.\r\n\r\ncontracts.ruby comes with a lot of built-in contracts, including the following:\r\n\r\n* [`Num`](http://www.rubydoc.info/gems/contracts/Contracts/Num) – checks that the argument is `Numeric`\r\n* [`Pos`](http://www.rubydoc.info/gems/contracts/Contracts/Pos) – checks that the argument is a positive number\r\n* [`Neg`](http://www.rubydoc.info/gems/contracts/Contracts/Neg) – checks that the argument is a negative number\r\n* [`Bool`](http://www.rubydoc.info/gems/contracts/Contracts/Bool) – checks that the argument is `true` or `false`\r\n* [`Any`](http://www.rubydoc.info/gems/contracts/Contracts/Any) – Passes for any argument. Use when the argument has no constraints.\r\n* [`None`](http://www.rubydoc.info/gems/contracts/Contracts/None) – Fails for any argument. Use when the method takes no arguments.\r\n* [`Or`](http://www.rubydoc.info/gems/contracts/Contracts/Or) – passes if any of the given contracts pass, e.g. `Or[Fixnum, Float]`\r\n* [`Xor`](http://www.rubydoc.info/gems/contracts/Contracts/Xor) – passes if exactly one of the given contracts pass, e.g. `Xor[Fixnum, Float]`\r\n* [`And`](http://www.rubydoc.info/gems/contracts/Contracts/And) – passes if all contracts pass, e.g. `And[Fixnum, Float]`\r\n* [`Not`](http://www.rubydoc.info/gems/contracts/Contracts/Not) – passes if all contracts fail for the given argument, e.g. `Not[nil]`\r\n* [`ArrayOf`](http://www.rubydoc.info/gems/contracts/Contracts/ArrayOf) – checks that the argument is an array, and all elements pass the given contract, e.g. `ArrayOf[Num]`\r\n* [`HashOf`](http://www.rubydoc.info/gems/contracts/Contracts/HashOf) – checks that the argument is a hash, and all keys and values pass the given contract, e.g. `HashOf[Symbol, String]`\r\n* [`Maybe`](http://www.rubydoc.info/gems/contracts/Contracts/Maybe) – passes if the argument is `nil`, or if the given contract passes\r\n* [`RespondTo`](http://www.rubydoc.info/gems/contracts/Contracts/RespondTo) – checks that the argument responds to all of the given methods, e.g. `RespondTo[:password, :credit_card]`\r\n* [`Send`](http://www.rubydoc.info/gems/contracts/Contracts/Send) – checks that all named methods return true, e.g. `Send[:valid?]`\r\n* [`Exactly`](http://www.rubydoc.info/gems/contracts/Contracts/Exactly) – checks that the argument has the given type, not accepting sub-classes, e.g. `Exactly[Numeric]`.\r\n\r\nTo see all the built-in contracts and their full descriptions, check out the [RDoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the built-in contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nLets say you are writing a simple map function:\r\n\r\n```ruby\r\ndef map(arr, func)\r\n```\r\n\r\n`map` takes an array, and a function. Suppose you want to add a contract to this function. You could try this:\r\n\r\n```ruby\r\nContract ArrayOf[Any], Proc => ArrayOf[Any]\r\ndef map(arr, func)\r\n```\r\n\r\nThis says that the second argument should be a `Proc`. You can call the function like so:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\n```\r\n\r\nBut suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nEarlier, we used `Proc`, which just says \"make sure the second variable is a Proc\". Now we are using `Func[Num => Num]`, which says \"make sure the second variable is a Proc that takes a number and returns a number\". Better!\r\n\r\nTry this map function with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\nNOTE: This is not valid:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func => ArrayOf[Num]\r\ndef map(arr, &func)\r\n```\r\n\r\nHere I am using `Func` without specifying a contract, like `Func[Num => Num]`. That's not a legal contract. If you just want to validate that the second argument is a proc, use `Proc`.\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! This is commonly called \"pattern matching\" in functional programming languages.\r\n\r\nFor example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\nThis allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:\r\n\r\n```ruby\r\nContract lambda{|n| n < 12 } => Ticket\r\ndef get_ticket(age)\r\n ChildTicket.new(age: age)\r\nend\r\n\r\nContract lambda{|n| n >= 12 } => Ticket\r\ndef get_ticket(age)\r\n AdultTicket.new(age: age)\r\nend\r\n\r\n```\r\n\r\nNote that the second `get_ticket` contract above could have been simplified to:\r\n\r\n```ruby\r\nContract Num => Ticket\r\n```\r\n\r\nThis is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to \"spell out\" the age condition for clarity, especially if the method is overloaded with many contracts.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n include Contracts\r\n include Contracts::Modules\r\n\r\n Contract String => String\r\n def self.parse\r\n # do some hard parsing\r\n end\r\nend\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts::Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 81cf55b0a439587ef615fdcfb9e29de75bcdb716 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Tue, 24 Mar 2015 12:28:05 -0700 Subject: [PATCH 16/19] Create gh-pages branch via GitHub --- index.html | 191 +++++++++++++++++++++-------------------- params.json | 2 +- stylesheets/styles.css | 2 +- 3 files changed, 101 insertions(+), 94 deletions(-) diff --git a/index.html b/index.html index 93dc96e..ea4ea50 100644 --- a/index.html +++ b/index.html @@ -52,8 +52,8 @@

      A simple example:

      -
      Contract Num, Num => Num
      -def add(a, b)
      +
      Contract Num, Num => Num
      +def add(a, b)
         a + b
       end
      @@ -61,18 +61,18 @@

      Copy this code into a file and run it:

      -
      require 'contracts'
      +
      require 'contracts'
       
       class Math
      -  include Contracts
      +  include Contracts
       
      -  Contract Num, Num => Num
      -  def self.add(a, b)
      +  Contract Num, Num => Num
      +  def self.add(a, b)
           a + b
         end
       end
       
      -puts Math.add(1, "foo")
      +puts Math.add(1, "foo")

      You'll see a detailed error message like so:

      @@ -111,6 +111,8 @@

    • Neg – checks that the argument is a negative number
    • +Nat – checks that the argument is a natural number
    • +
    • Bool – checks that the argument is true or false
    • @@ -155,9 +157,9 @@

      Hello, World

      -
      Contract String => nil
      -def hello(name)
      -  puts "hello, #{name}!"
      +
      Contract String => nil
      +def hello(name)
      +  puts "hello, #{name}!"
       end

      You always need to specify a contract for the return value. In this example, hello doesn't return anything, so the contract is nil. Now you know that you can use a constant like nil as the end of a contract. Valid values for a contract are:

      @@ -173,33 +175,33 @@

      A Double Function

      -
      Contract Or[Fixnum, Float] => Or[Fixnum, Float]
      -def double(x)
      +
      Contract Or[Fixnum, Float] => Or[Fixnum, Float]
      +def double(x)
         2 * x
       end

      Sometimes you want to be able to choose between a few contracts. Or takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the Or contract passes. This introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the valid? method. This is what Or[Fixnum, Float] is. The longer way to write it would have been:

      -
      Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
      +
      Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)

      All the built-in contracts have overridden the square brackets ([]) to give the same functionality. So you could write

      -
      Contract Or[Fixnum, Float] => Or[Fixnum, Float]
      +
      Contract Or[Fixnum, Float] => Or[Fixnum, Float]

      or

      -
      Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
      +
      Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)

      whichever you prefer. They both mean the same thing here: make a new instance of Or with Fixnum and Float. Use that instance to validate the argument.

      A Product Function

      -
      Contract ArrayOf[Num] => Num
      -def product(vals)
      +
      Contract ArrayOf[Num] => Num
      +def product(vals)
         total = 1
      -  vals.each do |val|
      +  vals.each do |val|
           total *= val
         end
         total
      @@ -211,15 +213,15 @@ 

      product([1, 2, 3, 4]) # fails -product([1, 2, 3, "foo"])

      +product([1, 2, 3, "foo"])

      Another Product Function

      -
      Contract Args[Num] => Num
      -def product(*vals)
      +
      Contract Args[Num] => Num
      +def product(*vals)
         total = 1
      -  vals.each do |val|
      +  vals.each do |val|
           total *= val
         end
         total
      @@ -239,8 +241,8 @@ 

      If an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:

      # a function that takes an array of two elements...a person's age and a person's name.
      -Contract [Num, String] => nil
      -def person(data)
      +Contract [Num, String] => nil
      +def person(data)
         p data
       end
      @@ -252,26 +254,26 @@

      Here's a contract that requires a Hash. We can put contracts on each of the keys:

      # note the parentheses around the hash; without those you would get a syntax error
      -Contract ({ :age => Num, :name => String }) => nil
      -def person(data)
      +Contract ({ :age => Num, :name => String }) => nil
      +def person(data)
         p data
       end

      Then if someone tries to call the function with bad data, it will fail:

      # error: age can't be nil!
      -person({:name => "Adit", :age => nil})
      +person({:name => "Adit", :age => nil})

      You don't need to put a contract on every key. So this call would succeed:

      -
      person({:name => "Adit", :age => 42, :foo => "bar"})
      +
      person({:name => "Adit", :age => 42, :foo => "bar"})

      even though we don't specify a type for :foo.

      Peruse this contract on the keys and values of a Hash.

      -
      Contract HashOf[Symbol, Num] => Num
      -def give_largest_value(hsh)
      +
      Contract HashOf[Symbol, Num] => Num
      +def give_largest_value(hsh)
         hsh.values.max
       end
      @@ -281,32 +283,32 @@

      give_largest_value(a: 1, b: 2, c: 3) # returns 3 # fails -give_largest_value("a" => 1, 2 => 2, c: 3)

      +give_largest_value("a" => 1, 2 => 2, c: 3)

      Contracts On Functions

      Lets say you are writing a simple map function:

      -
      def map(arr, func)
      +
      def map(arr, func)

      map takes an array, and a function. Suppose you want to add a contract to this function. You could try this:

      -
      Contract ArrayOf[Any], Proc => ArrayOf[Any]
      -def map(arr, func)
      +
      Contract ArrayOf[Any], Proc => ArrayOf[Any]
      +def map(arr, func)

      This says that the second argument should be a Proc. You can call the function like so:

      -
      p map([1, 2, 3], lambda { |x| x + 1 }) # works
      +
      p map([1, 2, 3], lambda { |x| x + 1 }) # works

      But suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the Func contract. Func takes a contract as it's argument, and uses that contract on the function that you pass in.

      Here's a map function that requires an array of numbers, and a function that takes a number and returns a number:

      -
      Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]
      -def map(arr, func)
      +
      Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]
      +def map(arr, func)
         ret = []
      -  arr.each do |x|
      +  arr.each do |x|
           ret << func[x]
         end
         ret
      @@ -316,13 +318,13 @@ 

      Try this map function with these two examples:

      -
      p map([1, 2, 3], lambda { |x| x + 1 }) # works
      -p map([1, 2, 3], lambda { |x| "oops" }) # fails, the lambda returns a string.
      +
      p map([1, 2, 3], lambda { |x| x + 1 }) # works
      +p map([1, 2, 3], lambda { |x| "oops" }) # fails, the lambda returns a string.

      NOTE: This is not valid:

      -
      Contract ArrayOf[Num], Func => ArrayOf[Num]
      -def map(arr, &func)
      +
      Contract ArrayOf[Num], Func => ArrayOf[Num]
      +def map(arr, &func)

      Here I am using Func without specifying a contract, like Func[Num => Num]. That's not a legal contract. If you just want to validate that the second argument is a proc, use Proc.

      @@ -331,8 +333,8 @@

      Treat the return value as an array. For example, here's a function that returns two numbers:

      -
      Contract Num => [Num, Num]
      -def mult(x)
      +
      Contract Num => [Num, Num]
      +def mult(x)
         return x, x+1
       end
      @@ -341,17 +343,17 @@

      If you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a Hash or nil. If a Hash is returned, it contains information about a person. Your contact might look like this:

      -
      Contract String => Or[Hash, nil]
      -def some_func(str)
      +
      Contract String => Or[Hash, nil]
      +def some_func(str)

      You can make your contract more meaningful with a synonym:

      # the synonym
      -Person = Or[Hash, nil]
      +Person = Or[Hash, nil]
       
       # use the synonym here
      -Contract String => Person
      -def some_func(str)
      +Contract String => Person +def some_func(str)

      Now you can use Person wherever you would have used Or[Hash, nil]. Your code is now cleaner and more clearly says what the function is doing.

      @@ -373,8 +375,8 @@

      A Proc

      -
      Contract lambda { |x| x.is_a? Numeric } => Num
      -def double(x)
      +
      Contract lambda { |x| x.is_a? Numeric } => Num
      +def double(x)

      The lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a Numeric. If it is, it returns true. Otherwise it returns false. It's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:

      @@ -385,8 +387,8 @@

      Here's how the Num class is defined. It does exactly what the lambda did in the previous example:

      class Num
      -  def self.valid? val
      -    val.is_a? Numeric
      +  def self.valid? val
      +    val.is_a? Numeric
         end
       end
      @@ -398,13 +400,13 @@

      Here's how the Or class is defined:

      class Or < CallableClass
      -  def initialize(*vals)
      -    @vals = vals
      +  def initialize(*vals)
      +    @vals = vals
         end
       
      -  def valid?(val)
      -    @vals.any? do |contract|
      -      res, _ = Contract.valid?(val, contract)
      +  def valid?(val)
      +    @vals.any? do |contract|
      +      res, _ = Contract.valid?(val, contract)
             res
           end
         end
      @@ -414,15 +416,15 @@ 

      This class inherits from CallableClass, which allows us to use [] when using the class:

      -
      Contract Or[Fixnum, Float] => Num
      -def double(x)
      +
      Contract Or[Fixnum, Float] => Num
      +def double(x)
         2 * x
       end

      Without CallableClass, we would have to use .new instead:

      -
      Contract Or.new(Fixnum, Float) => Num
      -def double(x)
      +
      Contract Or.new(Fixnum, Float) => Num
      +def double(x)
       # etc

      You can use CallableClass in your own contracts to make them callable using [].

      @@ -440,7 +442,7 @@

      You can customize this message by overriding the to_s method on your class or proc. For example, suppose we overrode Num's to_s method:

      def Num.to_s
      -  "a number please"
      +  "a number please"
       end

      Now the error says:

      @@ -457,8 +459,8 @@

      contracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:

      -
      Contract.override_failure_callback do |data|
      -  puts "You had an error"
      +
      Contract.override_failure_callback do |data|
      +  puts "You had an error"
         puts failure_msg(data)
       end
      @@ -487,8 +489,8 @@

      For example, here's a factorial function without method overloading:

      -
      Contract Num => Num
      -def fact x
      +
      Contract Num => Num
      +def fact x
         if x == 1
           x
         else
      @@ -498,13 +500,13 @@ 

      Here it is again, re-written with method overloading:

      -
      Contract 1 => 1
      -def fact x
      +
      Contract 1 => 1
      +def fact x
         x
       end
       
      -Contract Num => Num
      -def fact x
      +Contract Num => Num
      +def fact x
         x * fact(x - 1)
       end
      @@ -512,20 +514,20 @@

      This allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:

      -
      Contract lambda{|n| n < 12 } => Ticket
      -def get_ticket(age)
      -  ChildTicket.new(age: age)
      +
      Contract lambda{|n| n < 12 } => Ticket
      +def get_ticket(age)
      +  ChildTicket.new(age: age)
       end
       
      -Contract lambda{|n| n >= 12 } => Ticket
      -def get_ticket(age)
      -  AdultTicket.new(age: age)
      +Contract lambda{|n| n >= 12 } => Ticket
      +def get_ticket(age)
      +  AdultTicket.new(age: age)
       end
       

      Note that the second get_ticket contract above could have been simplified to:

      -
      Contract Num => Ticket
      +
      Contract Num => Ticket

      This is because the first contract eliminated the possibility of age being less than 12. However, the simpler contract is less explicit; you may want to "spell out" the age condition for clarity, especially if the method is overloaded with many contracts.

      @@ -535,10 +537,10 @@

      To use contracts on module you need to include both Contracts and Contracts::Modules into it:

      module M
      -  include Contracts
      -  include Contracts::Modules
      +  include Contracts
      +  include Contracts::Modules
       
      -  Contract String => String
      +  Contract String => String
         def self.parse
           # do some hard parsing
         end
      @@ -554,31 +556,36 @@ 

      A simple example:

      class MyBirthday < Struct.new(:day, :month)
      -  include Contracts
      -  include Contracts::Invariants
      +  include Contracts
      +  include Contracts::Invariants
       
      -  Invariant(:day) { 1 <= day && day <= 31 }
      -  Invariant(:month) { 1 <= month && month <= 12 }
      +  Invariant(:day) { 1 <= day && day <= 31 }
      +  Invariant(:month) { 1 <= month && month <= 12 }
       
      -  Contract None => Fixnum
      +  Contract None => Fixnum
         def silly_next_day!
           self.day += 1
         end
       end
       
      -birthday = MyBirthday.new(31, 12)
      +birthday = MyBirthday.new(31, 12)
       birthday.silly_next_day!

      If you run it, last line will generate invariant violation:

      -
      ./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)
      -   Expected: day condition to be true
      -   Actual: false
      -   Value guarded in: MyBirthday::silly_next_day!
      -   At: main.rb:9
      +
      ./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)
      +   Expected: day condition to be true
      +   Actual: false
      +   Value guarded in: MyBirthday::silly_next_day!
      +   At: main.rb:9

      Which means, that after #silly_next_day! all checks specified in Invariant statement will be verified, and if at least one fail, then Invariant violation error will be raised.

      +

      +Auto-generate documentation using contracts

      + +

      If you are generating documentation for your code with YARD, check out yard-contracts. It will automatically annotate your functions with contracts information. Instead of documenting each parameter for a function yourself, you can just add a contract and yard-contracts will generate the documentation for you!

      +

      Misc

      diff --git a/params.json b/params.json index 5594fbb..3360032 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\n\r\nclass Math\r\n include Contracts\r\n\r\n Contract Num, Num => Num\r\n def self.add(a, b)\r\n a + b\r\n end\r\nend\r\n\r\nputs Math.add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a REPL and want to figure out how a function should be used.\r\n\r\n## Built-in Contracts\r\n\r\n`Num` is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts` module in your class/module.\r\n\r\ncontracts.ruby comes with a lot of built-in contracts, including the following:\r\n\r\n* [`Num`](http://www.rubydoc.info/gems/contracts/Contracts/Num) – checks that the argument is `Numeric`\r\n* [`Pos`](http://www.rubydoc.info/gems/contracts/Contracts/Pos) – checks that the argument is a positive number\r\n* [`Neg`](http://www.rubydoc.info/gems/contracts/Contracts/Neg) – checks that the argument is a negative number\r\n* [`Bool`](http://www.rubydoc.info/gems/contracts/Contracts/Bool) – checks that the argument is `true` or `false`\r\n* [`Any`](http://www.rubydoc.info/gems/contracts/Contracts/Any) – Passes for any argument. Use when the argument has no constraints.\r\n* [`None`](http://www.rubydoc.info/gems/contracts/Contracts/None) – Fails for any argument. Use when the method takes no arguments.\r\n* [`Or`](http://www.rubydoc.info/gems/contracts/Contracts/Or) – passes if any of the given contracts pass, e.g. `Or[Fixnum, Float]`\r\n* [`Xor`](http://www.rubydoc.info/gems/contracts/Contracts/Xor) – passes if exactly one of the given contracts pass, e.g. `Xor[Fixnum, Float]`\r\n* [`And`](http://www.rubydoc.info/gems/contracts/Contracts/And) – passes if all contracts pass, e.g. `And[Fixnum, Float]`\r\n* [`Not`](http://www.rubydoc.info/gems/contracts/Contracts/Not) – passes if all contracts fail for the given argument, e.g. `Not[nil]`\r\n* [`ArrayOf`](http://www.rubydoc.info/gems/contracts/Contracts/ArrayOf) – checks that the argument is an array, and all elements pass the given contract, e.g. `ArrayOf[Num]`\r\n* [`HashOf`](http://www.rubydoc.info/gems/contracts/Contracts/HashOf) – checks that the argument is a hash, and all keys and values pass the given contract, e.g. `HashOf[Symbol, String]`\r\n* [`Maybe`](http://www.rubydoc.info/gems/contracts/Contracts/Maybe) – passes if the argument is `nil`, or if the given contract passes\r\n* [`RespondTo`](http://www.rubydoc.info/gems/contracts/Contracts/RespondTo) – checks that the argument responds to all of the given methods, e.g. `RespondTo[:password, :credit_card]`\r\n* [`Send`](http://www.rubydoc.info/gems/contracts/Contracts/Send) – checks that all named methods return true, e.g. `Send[:valid?]`\r\n* [`Exactly`](http://www.rubydoc.info/gems/contracts/Contracts/Exactly) – checks that the argument has the given type, not accepting sub-classes, e.g. `Exactly[Numeric]`.\r\n\r\nTo see all the built-in contracts and their full descriptions, check out the [RDoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the built-in contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nLets say you are writing a simple map function:\r\n\r\n```ruby\r\ndef map(arr, func)\r\n```\r\n\r\n`map` takes an array, and a function. Suppose you want to add a contract to this function. You could try this:\r\n\r\n```ruby\r\nContract ArrayOf[Any], Proc => ArrayOf[Any]\r\ndef map(arr, func)\r\n```\r\n\r\nThis says that the second argument should be a `Proc`. You can call the function like so:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\n```\r\n\r\nBut suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nEarlier, we used `Proc`, which just says \"make sure the second variable is a Proc\". Now we are using `Func[Num => Num]`, which says \"make sure the second variable is a Proc that takes a number and returns a number\". Better!\r\n\r\nTry this map function with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\nNOTE: This is not valid:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func => ArrayOf[Num]\r\ndef map(arr, &func)\r\n```\r\n\r\nHere I am using `Func` without specifying a contract, like `Func[Num => Num]`. That's not a legal contract. If you just want to validate that the second argument is a proc, use `Proc`.\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! This is commonly called \"pattern matching\" in functional programming languages.\r\n\r\nFor example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\nThis allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:\r\n\r\n```ruby\r\nContract lambda{|n| n < 12 } => Ticket\r\ndef get_ticket(age)\r\n ChildTicket.new(age: age)\r\nend\r\n\r\nContract lambda{|n| n >= 12 } => Ticket\r\ndef get_ticket(age)\r\n AdultTicket.new(age: age)\r\nend\r\n\r\n```\r\n\r\nNote that the second `get_ticket` contract above could have been simplified to:\r\n\r\n```ruby\r\nContract Num => Ticket\r\n```\r\n\r\nThis is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to \"spell out\" the age condition for clarity, especially if the method is overloaded with many contracts.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n include Contracts\r\n include Contracts::Modules\r\n\r\n Contract String => String\r\n def self.parse\r\n # do some hard parsing\r\n end\r\nend\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts::Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\n\r\nclass Math\r\n include Contracts\r\n\r\n Contract Num, Num => Num\r\n def self.add(a, b)\r\n a + b\r\n end\r\nend\r\n\r\nputs Math.add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a REPL and want to figure out how a function should be used.\r\n\r\n## Built-in Contracts\r\n\r\n`Num` is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts` module in your class/module.\r\n\r\ncontracts.ruby comes with a lot of built-in contracts, including the following:\r\n\r\n* [`Num`](http://www.rubydoc.info/gems/contracts/Contracts/Num) – checks that the argument is `Numeric`\r\n* [`Pos`](http://www.rubydoc.info/gems/contracts/Contracts/Pos) – checks that the argument is a positive number\r\n* [`Neg`](http://www.rubydoc.info/gems/contracts/Contracts/Neg) – checks that the argument is a negative number\r\n* [`Nat`](http://www.rubydoc.info/gems/contracts/Contracts/Nat) – checks that the argument is a natural number\r\n* [`Bool`](http://www.rubydoc.info/gems/contracts/Contracts/Bool) – checks that the argument is `true` or `false`\r\n* [`Any`](http://www.rubydoc.info/gems/contracts/Contracts/Any) – Passes for any argument. Use when the argument has no constraints.\r\n* [`None`](http://www.rubydoc.info/gems/contracts/Contracts/None) – Fails for any argument. Use when the method takes no arguments.\r\n* [`Or`](http://www.rubydoc.info/gems/contracts/Contracts/Or) – passes if any of the given contracts pass, e.g. `Or[Fixnum, Float]`\r\n* [`Xor`](http://www.rubydoc.info/gems/contracts/Contracts/Xor) – passes if exactly one of the given contracts pass, e.g. `Xor[Fixnum, Float]`\r\n* [`And`](http://www.rubydoc.info/gems/contracts/Contracts/And) – passes if all contracts pass, e.g. `And[Fixnum, Float]`\r\n* [`Not`](http://www.rubydoc.info/gems/contracts/Contracts/Not) – passes if all contracts fail for the given argument, e.g. `Not[nil]`\r\n* [`ArrayOf`](http://www.rubydoc.info/gems/contracts/Contracts/ArrayOf) – checks that the argument is an array, and all elements pass the given contract, e.g. `ArrayOf[Num]`\r\n* [`HashOf`](http://www.rubydoc.info/gems/contracts/Contracts/HashOf) – checks that the argument is a hash, and all keys and values pass the given contract, e.g. `HashOf[Symbol, String]`\r\n* [`Maybe`](http://www.rubydoc.info/gems/contracts/Contracts/Maybe) – passes if the argument is `nil`, or if the given contract passes\r\n* [`RespondTo`](http://www.rubydoc.info/gems/contracts/Contracts/RespondTo) – checks that the argument responds to all of the given methods, e.g. `RespondTo[:password, :credit_card]`\r\n* [`Send`](http://www.rubydoc.info/gems/contracts/Contracts/Send) – checks that all named methods return true, e.g. `Send[:valid?]`\r\n* [`Exactly`](http://www.rubydoc.info/gems/contracts/Contracts/Exactly) – checks that the argument has the given type, not accepting sub-classes, e.g. `Exactly[Numeric]`.\r\n\r\nTo see all the built-in contracts and their full descriptions, check out the [RDoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the built-in contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nLets say you are writing a simple map function:\r\n\r\n```ruby\r\ndef map(arr, func)\r\n```\r\n\r\n`map` takes an array, and a function. Suppose you want to add a contract to this function. You could try this:\r\n\r\n```ruby\r\nContract ArrayOf[Any], Proc => ArrayOf[Any]\r\ndef map(arr, func)\r\n```\r\n\r\nThis says that the second argument should be a `Proc`. You can call the function like so:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\n```\r\n\r\nBut suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nEarlier, we used `Proc`, which just says \"make sure the second variable is a Proc\". Now we are using `Func[Num => Num]`, which says \"make sure the second variable is a Proc that takes a number and returns a number\". Better!\r\n\r\nTry this map function with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\nNOTE: This is not valid:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func => ArrayOf[Num]\r\ndef map(arr, &func)\r\n```\r\n\r\nHere I am using `Func` without specifying a contract, like `Func[Num => Num]`. That's not a legal contract. If you just want to validate that the second argument is a proc, use `Proc`.\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! This is commonly called \"pattern matching\" in functional programming languages.\r\n\r\nFor example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\nThis allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:\r\n\r\n```ruby\r\nContract lambda{|n| n < 12 } => Ticket\r\ndef get_ticket(age)\r\n ChildTicket.new(age: age)\r\nend\r\n\r\nContract lambda{|n| n >= 12 } => Ticket\r\ndef get_ticket(age)\r\n AdultTicket.new(age: age)\r\nend\r\n\r\n```\r\n\r\nNote that the second `get_ticket` contract above could have been simplified to:\r\n\r\n```ruby\r\nContract Num => Ticket\r\n```\r\n\r\nThis is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to \"spell out\" the age condition for clarity, especially if the method is overloaded with many contracts.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n include Contracts\r\n include Contracts::Modules\r\n\r\n Contract String => String\r\n def self.parse\r\n # do some hard parsing\r\n end\r\nend\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts::Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Auto-generate documentation using contracts\r\n\r\nIf you are generating documentation for your code with [YARD](http://yardoc.org/), check out [yard-contracts](https://github.com/sfcgeorge/yard-contracts). It will automatically annotate your functions with contracts information. Instead of documenting each parameter for a function yourself, you can just add a contract and yard-contracts will generate the documentation for you!\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/stylesheets/styles.css b/stylesheets/styles.css index 466b9d6..455c7ef 100644 --- a/stylesheets/styles.css +++ b/stylesheets/styles.css @@ -351,6 +351,6 @@ footer p + p { } @media print { header p.view a small:before { - content: 'at http://github.com/'; + content: 'at https://github.com/'; } } From 5ab9ac6f395a0371a109af02b7ff043e10c3b515 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Sun, 12 Apr 2015 22:14:19 -0700 Subject: [PATCH 17/19] Create gh-pages branch via GitHub --- index.html | 6 +++--- params.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index ea4ea50..0f4c1d2 100644 --- a/index.html +++ b/index.html @@ -559,8 +559,8 @@

      include Contracts include Contracts::Invariants - Invariant(:day) { 1 <= day && day <= 31 } - Invariant(:month) { 1 <= month && month <= 12 } + invariant(:day) { 1 <= day && day <= 31 } + invariant(:month) { 1 <= month && month <= 12 } Contract None => Fixnum def silly_next_day! @@ -579,7 +579,7 @@

      Value guarded in: MyBirthday::silly_next_day! At: main.rb:9

      -

      Which means, that after #silly_next_day! all checks specified in Invariant statement will be verified, and if at least one fail, then Invariant violation error will be raised.

      +

      Which means, that after #silly_next_day! all checks specified in invariant statement will be verified, and if at least one fail, then invariant violation error will be raised.

      Auto-generate documentation using contracts

      diff --git a/params.json b/params.json index 3360032..c2e88c1 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\n\r\nclass Math\r\n include Contracts\r\n\r\n Contract Num, Num => Num\r\n def self.add(a, b)\r\n a + b\r\n end\r\nend\r\n\r\nputs Math.add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a REPL and want to figure out how a function should be used.\r\n\r\n## Built-in Contracts\r\n\r\n`Num` is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts` module in your class/module.\r\n\r\ncontracts.ruby comes with a lot of built-in contracts, including the following:\r\n\r\n* [`Num`](http://www.rubydoc.info/gems/contracts/Contracts/Num) – checks that the argument is `Numeric`\r\n* [`Pos`](http://www.rubydoc.info/gems/contracts/Contracts/Pos) – checks that the argument is a positive number\r\n* [`Neg`](http://www.rubydoc.info/gems/contracts/Contracts/Neg) – checks that the argument is a negative number\r\n* [`Nat`](http://www.rubydoc.info/gems/contracts/Contracts/Nat) – checks that the argument is a natural number\r\n* [`Bool`](http://www.rubydoc.info/gems/contracts/Contracts/Bool) – checks that the argument is `true` or `false`\r\n* [`Any`](http://www.rubydoc.info/gems/contracts/Contracts/Any) – Passes for any argument. Use when the argument has no constraints.\r\n* [`None`](http://www.rubydoc.info/gems/contracts/Contracts/None) – Fails for any argument. Use when the method takes no arguments.\r\n* [`Or`](http://www.rubydoc.info/gems/contracts/Contracts/Or) – passes if any of the given contracts pass, e.g. `Or[Fixnum, Float]`\r\n* [`Xor`](http://www.rubydoc.info/gems/contracts/Contracts/Xor) – passes if exactly one of the given contracts pass, e.g. `Xor[Fixnum, Float]`\r\n* [`And`](http://www.rubydoc.info/gems/contracts/Contracts/And) – passes if all contracts pass, e.g. `And[Fixnum, Float]`\r\n* [`Not`](http://www.rubydoc.info/gems/contracts/Contracts/Not) – passes if all contracts fail for the given argument, e.g. `Not[nil]`\r\n* [`ArrayOf`](http://www.rubydoc.info/gems/contracts/Contracts/ArrayOf) – checks that the argument is an array, and all elements pass the given contract, e.g. `ArrayOf[Num]`\r\n* [`HashOf`](http://www.rubydoc.info/gems/contracts/Contracts/HashOf) – checks that the argument is a hash, and all keys and values pass the given contract, e.g. `HashOf[Symbol, String]`\r\n* [`Maybe`](http://www.rubydoc.info/gems/contracts/Contracts/Maybe) – passes if the argument is `nil`, or if the given contract passes\r\n* [`RespondTo`](http://www.rubydoc.info/gems/contracts/Contracts/RespondTo) – checks that the argument responds to all of the given methods, e.g. `RespondTo[:password, :credit_card]`\r\n* [`Send`](http://www.rubydoc.info/gems/contracts/Contracts/Send) – checks that all named methods return true, e.g. `Send[:valid?]`\r\n* [`Exactly`](http://www.rubydoc.info/gems/contracts/Contracts/Exactly) – checks that the argument has the given type, not accepting sub-classes, e.g. `Exactly[Numeric]`.\r\n\r\nTo see all the built-in contracts and their full descriptions, check out the [RDoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the built-in contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nLets say you are writing a simple map function:\r\n\r\n```ruby\r\ndef map(arr, func)\r\n```\r\n\r\n`map` takes an array, and a function. Suppose you want to add a contract to this function. You could try this:\r\n\r\n```ruby\r\nContract ArrayOf[Any], Proc => ArrayOf[Any]\r\ndef map(arr, func)\r\n```\r\n\r\nThis says that the second argument should be a `Proc`. You can call the function like so:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\n```\r\n\r\nBut suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nEarlier, we used `Proc`, which just says \"make sure the second variable is a Proc\". Now we are using `Func[Num => Num]`, which says \"make sure the second variable is a Proc that takes a number and returns a number\". Better!\r\n\r\nTry this map function with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\nNOTE: This is not valid:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func => ArrayOf[Num]\r\ndef map(arr, &func)\r\n```\r\n\r\nHere I am using `Func` without specifying a contract, like `Func[Num => Num]`. That's not a legal contract. If you just want to validate that the second argument is a proc, use `Proc`.\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! This is commonly called \"pattern matching\" in functional programming languages.\r\n\r\nFor example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\nThis allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:\r\n\r\n```ruby\r\nContract lambda{|n| n < 12 } => Ticket\r\ndef get_ticket(age)\r\n ChildTicket.new(age: age)\r\nend\r\n\r\nContract lambda{|n| n >= 12 } => Ticket\r\ndef get_ticket(age)\r\n AdultTicket.new(age: age)\r\nend\r\n\r\n```\r\n\r\nNote that the second `get_ticket` contract above could have been simplified to:\r\n\r\n```ruby\r\nContract Num => Ticket\r\n```\r\n\r\nThis is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to \"spell out\" the age condition for clarity, especially if the method is overloaded with many contracts.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n include Contracts\r\n include Contracts::Modules\r\n\r\n Contract String => String\r\n def self.parse\r\n # do some hard parsing\r\n end\r\nend\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts::Invariants\r\n\r\n Invariant(:day) { 1 <= day && day <= 31 }\r\n Invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `Invariant` statement will be verified, and if at least one fail, then Invariant violation error will be raised.\r\n\r\n## Auto-generate documentation using contracts\r\n\r\nIf you are generating documentation for your code with [YARD](http://yardoc.org/), check out [yard-contracts](https://github.com/sfcgeorge/yard-contracts). It will automatically annotate your functions with contracts information. Instead of documenting each parameter for a function yourself, you can just add a contract and yard-contracts will generate the documentation for you!\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\n\r\nclass Math\r\n include Contracts\r\n\r\n Contract Num, Num => Num\r\n def self.add(a, b)\r\n a + b\r\n end\r\nend\r\n\r\nputs Math.add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a REPL and want to figure out how a function should be used.\r\n\r\n## Built-in Contracts\r\n\r\n`Num` is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts` module in your class/module.\r\n\r\ncontracts.ruby comes with a lot of built-in contracts, including the following:\r\n\r\n* [`Num`](http://www.rubydoc.info/gems/contracts/Contracts/Num) – checks that the argument is `Numeric`\r\n* [`Pos`](http://www.rubydoc.info/gems/contracts/Contracts/Pos) – checks that the argument is a positive number\r\n* [`Neg`](http://www.rubydoc.info/gems/contracts/Contracts/Neg) – checks that the argument is a negative number\r\n* [`Nat`](http://www.rubydoc.info/gems/contracts/Contracts/Nat) – checks that the argument is a natural number\r\n* [`Bool`](http://www.rubydoc.info/gems/contracts/Contracts/Bool) – checks that the argument is `true` or `false`\r\n* [`Any`](http://www.rubydoc.info/gems/contracts/Contracts/Any) – Passes for any argument. Use when the argument has no constraints.\r\n* [`None`](http://www.rubydoc.info/gems/contracts/Contracts/None) – Fails for any argument. Use when the method takes no arguments.\r\n* [`Or`](http://www.rubydoc.info/gems/contracts/Contracts/Or) – passes if any of the given contracts pass, e.g. `Or[Fixnum, Float]`\r\n* [`Xor`](http://www.rubydoc.info/gems/contracts/Contracts/Xor) – passes if exactly one of the given contracts pass, e.g. `Xor[Fixnum, Float]`\r\n* [`And`](http://www.rubydoc.info/gems/contracts/Contracts/And) – passes if all contracts pass, e.g. `And[Fixnum, Float]`\r\n* [`Not`](http://www.rubydoc.info/gems/contracts/Contracts/Not) – passes if all contracts fail for the given argument, e.g. `Not[nil]`\r\n* [`ArrayOf`](http://www.rubydoc.info/gems/contracts/Contracts/ArrayOf) – checks that the argument is an array, and all elements pass the given contract, e.g. `ArrayOf[Num]`\r\n* [`HashOf`](http://www.rubydoc.info/gems/contracts/Contracts/HashOf) – checks that the argument is a hash, and all keys and values pass the given contract, e.g. `HashOf[Symbol, String]`\r\n* [`Maybe`](http://www.rubydoc.info/gems/contracts/Contracts/Maybe) – passes if the argument is `nil`, or if the given contract passes\r\n* [`RespondTo`](http://www.rubydoc.info/gems/contracts/Contracts/RespondTo) – checks that the argument responds to all of the given methods, e.g. `RespondTo[:password, :credit_card]`\r\n* [`Send`](http://www.rubydoc.info/gems/contracts/Contracts/Send) – checks that all named methods return true, e.g. `Send[:valid?]`\r\n* [`Exactly`](http://www.rubydoc.info/gems/contracts/Contracts/Exactly) – checks that the argument has the given type, not accepting sub-classes, e.g. `Exactly[Numeric]`.\r\n\r\nTo see all the built-in contracts and their full descriptions, check out the [RDoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the built-in contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nLets say you are writing a simple map function:\r\n\r\n```ruby\r\ndef map(arr, func)\r\n```\r\n\r\n`map` takes an array, and a function. Suppose you want to add a contract to this function. You could try this:\r\n\r\n```ruby\r\nContract ArrayOf[Any], Proc => ArrayOf[Any]\r\ndef map(arr, func)\r\n```\r\n\r\nThis says that the second argument should be a `Proc`. You can call the function like so:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\n```\r\n\r\nBut suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nEarlier, we used `Proc`, which just says \"make sure the second variable is a Proc\". Now we are using `Func[Num => Num]`, which says \"make sure the second variable is a Proc that takes a number and returns a number\". Better!\r\n\r\nTry this map function with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\nNOTE: This is not valid:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func => ArrayOf[Num]\r\ndef map(arr, &func)\r\n```\r\n\r\nHere I am using `Func` without specifying a contract, like `Func[Num => Num]`. That's not a legal contract. If you just want to validate that the second argument is a proc, use `Proc`.\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! This is commonly called \"pattern matching\" in functional programming languages.\r\n\r\nFor example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\nThis allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:\r\n\r\n```ruby\r\nContract lambda{|n| n < 12 } => Ticket\r\ndef get_ticket(age)\r\n ChildTicket.new(age: age)\r\nend\r\n\r\nContract lambda{|n| n >= 12 } => Ticket\r\ndef get_ticket(age)\r\n AdultTicket.new(age: age)\r\nend\r\n\r\n```\r\n\r\nNote that the second `get_ticket` contract above could have been simplified to:\r\n\r\n```ruby\r\nContract Num => Ticket\r\n```\r\n\r\nThis is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to \"spell out\" the age condition for clarity, especially if the method is overloaded with many contracts.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n include Contracts\r\n include Contracts::Modules\r\n\r\n Contract String => String\r\n def self.parse\r\n # do some hard parsing\r\n end\r\nend\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts::Invariants\r\n\r\n invariant(:day) { 1 <= day && day <= 31 }\r\n invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `invariant` statement will be verified, and if at least one fail, then invariant violation error will be raised.\r\n\r\n## Auto-generate documentation using contracts\r\n\r\nIf you are generating documentation for your code with [YARD](http://yardoc.org/), check out [yard-contracts](https://github.com/sfcgeorge/yard-contracts). It will automatically annotate your functions with contracts information. Instead of documenting each parameter for a function yourself, you can just add a contract and yard-contracts will generate the documentation for you!\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 1be5d25f1030e446bc984b1127eae970f1950b23 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Thu, 14 May 2015 16:15:19 -0700 Subject: [PATCH 18/19] Create gh-pages branch via GitHub --- index.html | 4 +- stylesheets/github-dark.css | 116 ++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 stylesheets/github-dark.css diff --git a/index.html b/index.html index 0f4c1d2..e68eea9 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ Contracts.ruby by egonSchiele - + @@ -617,4 +617,4 @@

      - \ No newline at end of file + diff --git a/stylesheets/github-dark.css b/stylesheets/github-dark.css new file mode 100644 index 0000000..0c393bf --- /dev/null +++ b/stylesheets/github-dark.css @@ -0,0 +1,116 @@ +/* + Copyright 2014 GitHub Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +.pl-c /* comment */ { + color: #969896; +} + +.pl-c1 /* constant, markup.raw, meta.diff.header, meta.module-reference, meta.property-name, support, support.constant, support.variable, variable.other.constant */, +.pl-s .pl-v /* string variable */ { + color: #0099cd; +} + +.pl-e /* entity */, +.pl-en /* entity.name */ { + color: #9774cb; +} + +.pl-s .pl-s1 /* string source */, +.pl-smi /* storage.modifier.import, storage.modifier.package, storage.type.java, variable.other, variable.parameter.function */ { + color: #ddd; +} + +.pl-ent /* entity.name.tag */ { + color: #7bcc72; +} + +.pl-k /* keyword, storage, storage.type */ { + color: #cc2372; +} + +.pl-pds /* punctuation.definition.string, string.regexp.character-class */, +.pl-s /* string */, +.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */, +.pl-sr /* string.regexp */, +.pl-sr .pl-cce /* string.regexp constant.character.escape */, +.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */, +.pl-sr .pl-sre /* string.regexp source.ruby.embedded */ { + color: #3c66e2; +} + +.pl-v /* variable */ { + color: #fb8764; +} + +.pl-id /* invalid.deprecated */ { + color: #e63525; +} + +.pl-ii /* invalid.illegal */ { + background-color: #e63525; + color: #f8f8f8; +} + +.pl-sr .pl-cce /* string.regexp constant.character.escape */ { + color: #7bcc72; + font-weight: bold; +} + +.pl-ml /* markup.list */ { + color: #c26b2b; +} + +.pl-mh /* markup.heading */, +.pl-mh .pl-en /* markup.heading entity.name */, +.pl-ms /* meta.separator */ { + color: #264ec5; + font-weight: bold; +} + +.pl-mq /* markup.quote */ { + color: #00acac; +} + +.pl-mi /* markup.italic */ { + color: #ddd; + font-style: italic; +} + +.pl-mb /* markup.bold */ { + color: #ddd; + font-weight: bold; +} + +.pl-md /* markup.deleted, meta.diff.header.from-file */ { + background-color: #ffecec; + color: #bd2c00; +} + +.pl-mi1 /* markup.inserted, meta.diff.header.to-file */ { + background-color: #eaffea; + color: #55a532; +} + +.pl-mdr /* meta.diff.range */ { + color: #9774cb; + font-weight: bold; +} + +.pl-mo /* meta.output */ { + color: #264ec5; +} + From d79ef9c8be810b940fe28ced62720948a78dce80 Mon Sep 17 00:00:00 2001 From: Aditya Bhargava Date: Thu, 17 Sep 2015 09:13:30 -0700 Subject: [PATCH 19/19] Create gh-pages branch via GitHub --- index.html | 311 ++++++++++++++++++++++++++++++++++++++++++---------- params.json | 2 +- 2 files changed, 256 insertions(+), 57 deletions(-) diff --git a/index.html b/index.html index e68eea9..b3447a8 100644 --- a/index.html +++ b/index.html @@ -52,7 +52,7 @@

      A simple example:

      -
      Contract Num, Num => Num
      +
      Contract Contracts::Num, Contracts::Num => Contracts::Num
       def add(a, b)
         a + b
       end
      @@ -61,12 +61,12 @@

      Copy this code into a file and run it:

      -
      require 'contracts'
      +
      require 'contracts'
       
       class Math
      -  include Contracts
      +  include Contracts::Core
       
      -  Contract Num, Num => Num
      +  Contract Contracts::Num, Contracts::Num => Contracts::Num
         def self.add(a, b)
           a + b
         end
      @@ -98,10 +98,14 @@ 

      Built-in Contracts

      -

      Num is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the Contracts namespace. The easiest way to use them is to include the Contracts module in your class/module.

      +

      Num is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the Contracts namespace. The easiest way to use them is to include the Contracts::Builtin module in your class/module.

      contracts.ruby comes with a lot of built-in contracts, including the following:

      +
        +
      • +

        Basic types

        +
        • Num – checks that the argument is Numeric @@ -111,7 +115,7 @@

        • Neg – checks that the argument is a negative number
        • -Nat – checks that the argument is a natural number
        • +Nat – checks that the argument is a natural number (>= 0)

        • Bool – checks that the argument is true or false
        • @@ -119,6 +123,14 @@

          Any – Passes for any argument. Use when the argument has no constraints.
        • None – Fails for any argument. Use when the method takes no arguments.
        • +

        +
      • +
      • +

        Logical combinations

        + +
          +
        • +Maybe – specifies that a value may be nil, e.g. Maybe[String] (equivalent to Or[String,nil])
        • Or – passes if any of the given contracts pass, e.g. Or[Fixnum, Float]
        • @@ -126,38 +138,108 @@

          Xor – passes if exactly one of the given contracts pass, e.g. Xor[Fixnum, Float]
        • -And – passes if all contracts pass, e.g. And[Fixnum, Float] +And – passes if all contracts pass, e.g. And[Nat, -> (n) { n.even? }]
        • Not – passes if all contracts fail for the given argument, e.g. Not[nil]
        • +

        +
      • +
      • +

        Collections

        + +
        • ArrayOf – checks that the argument is an array, and all elements pass the given contract, e.g. ArrayOf[Num]
        • -HashOf – checks that the argument is a hash, and all keys and values pass the given contract, e.g. HashOf[Symbol, String] +SetOf – checks that the argument is a set, and all elements pass the given contract, e.g. SetOf[Num] +
        • +
        • +HashOf – checks that the argument is a hash, and all keys and values pass the given contract, e.g. HashOf[Symbol => String] or HashOf[Symbol,String] +
        • +
        • +RangeOf – checks that the argument is a range whose elements (#first and #last) pass the given contract, e.g. RangeOf[Date] +
        • +
        • +Enum – checks that the argument is part of a given collection of objects, e.g. Enum[:a, :b, :c] +
        • +
        +
      • +
      • +

        Keyword arguments

        + +
          +
        • +KeywordArgs – checks that the argument is an options hash, and all required keyword arguments are present, and all values pass their respective contracts, e.g. KeywordArgs[:number => Num, :description => Optional[String]] +
        • +
        • +Optional – checks that the keyword argument is either not present or pass the given contract, can not be used outside of KeywordArgs contract, e.g. Optional[Num] +
        • +
      • -Maybe – passes if the argument is nil, or if the given contract passes
      • +

        Duck typing

        + +
        • RespondTo – checks that the argument responds to all of the given methods, e.g. RespondTo[:password, :credit_card]
        • -Send – checks that all named methods return true, e.g. Send[:valid?] +Send – checks that all named methods return a truthy value, e.g. Send[:valid?] +
        • +
      • +

        Miscellaneous

        + +
          +
        • Exactly – checks that the argument has the given type, not accepting sub-classes, e.g. Exactly[Numeric].
        • +
        • +Eq – checks that the argument is precisely equal to the given value, e.g. Eq[String] matches the class String and not a string instance.
        • +
        • +Func – specifies the contract for a proc/lambda e.g. Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]. See section "Contracts On Functions".
        • +
        +

      To see all the built-in contracts and their full descriptions, check out the RDoc.

      +

      It is recommended to use shortcut for referring builtin contracts:

      + +
      # define shortcut somewhere at the top level of your codebase:
      +C = Contracts
      +
      +# and use it:
      +Contract C::Maybe[C::Num], String => C::Num
      + +

      Shortcut name should not be necessary C, can be anything that you are comfort +with while typing and anything that does not conflict with libraries you use.

      + +

      All examples after this point assume you have chosen a shortcut as C::.

      + +

      If you are sure, that builtin contracts will not nameclash with your own code +and libraries you may use, then you can include all builtin contracts in your +class/module:

      + +
      class Example
      +  include Contracts::Core
      +  include Contracts::Builtin
      +
      +  Contract Maybe[Num], Or[Float, String] => Bool
      +  def complicated_algorithm(a, b)
      +    # ...
      +  end
      +end
      +

      More Examples

      Hello, World

      -
      Contract String => nil
      +
      Contract String => nil
       def hello(name)
         puts "hello, #{name}!"
       end
      @@ -175,7 +257,7 @@

      A Double Function

      -
      Contract Or[Fixnum, Float] => Or[Fixnum, Float]
      +
      Contract C::Or[Fixnum, Float] => C::Or[Fixnum, Float]
       def double(x)
         2 * x
       end
      @@ -183,22 +265,22 @@

      Sometimes you want to be able to choose between a few contracts. Or takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the Or contract passes. This introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the valid? method. This is what Or[Fixnum, Float] is. The longer way to write it would have been:

      -
      Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
      +
      Contract C::Or.new(Fixnum, Float) => C::Or.new(Fixnum, Float)

      All the built-in contracts have overridden the square brackets ([]) to give the same functionality. So you could write

      -
      Contract Or[Fixnum, Float] => Or[Fixnum, Float]
      +
      Contract C::Or[Fixnum, Float] => C::Or[Fixnum, Float]

      or

      -
      Contract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)
      +
      Contract C::Or.new(Fixnum, Float) => C::Or.new(Fixnum, Float)

      whichever you prefer. They both mean the same thing here: make a new instance of Or with Fixnum and Float. Use that instance to validate the argument.

      A Product Function

      -
      Contract ArrayOf[Num] => Num
      +
      Contract C::ArrayOf[C::Num] => C::Num
       def product(vals)
         total = 1
         vals.each do |val|
      @@ -209,7 +291,7 @@ 

      This contract uses the ArrayOf contract. Here's how ArrayOf works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.

      -
      # passes
      +
      # passes
       product([1, 2, 3, 4])
       
       # fails
      @@ -218,7 +300,7 @@ 

      Another Product Function

      -
      Contract Args[Num] => Num
      +
      Contract C::Args[C::Num] => C::Num
       def product(*vals)
         total = 1
         vals.each do |val|
      @@ -240,8 +322,8 @@ 

      If an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:

      -
      # a function that takes an array of two elements...a person's age and a person's name.
      -Contract [Num, String] => nil
      +
      # a function that takes an array of two elements...a person's age and a person's name.
      +Contract [C::Num, String] => nil
       def person(data)
         p data
       end
      @@ -253,59 +335,119 @@

      Here's a contract that requires a Hash. We can put contracts on each of the keys:

      -
      # note the parentheses around the hash; without those you would get a syntax error
      -Contract ({ :age => Num, :name => String }) => nil
      +
      # note the parentheses around the hash; without those you would get a syntax error
      +Contract ({ :age => C::Num, :name => String }) => nil
       def person(data)
         p data
       end

      Then if someone tries to call the function with bad data, it will fail:

      -
      # error: age can't be nil!
      +
      # error: age can't be nil!
       person({:name => "Adit", :age => nil})

      You don't need to put a contract on every key. So this call would succeed:

      -
      person({:name => "Adit", :age => 42, :foo => "bar"})
      +
      person({:name => "Adit", :age => 42, :foo => "bar"})

      even though we don't specify a type for :foo.

      Peruse this contract on the keys and values of a Hash.

      -
      Contract HashOf[Symbol, Num] => Num
      +
      Contract C::HashOf[Symbol, C::Num] => C::Num
       def give_largest_value(hsh)
         hsh.values.max
       end

      Which you use like so:

      -
      # succeeds
      +
      # succeeds
       give_largest_value(a: 1, b: 2, c: 3) # returns 3
       
       # fails
       give_largest_value("a" => 1, 2 => 2, c: 3)
      +

      +Contracts On Strings

      + +

      When you want a contract to match not just any string (i.e. Contract String => nil), you can use regular expressions:

      + +
      Contract /World|Mars/i => nil
      +def greet(name)
      +  puts "Hello #{name}!"
      +end
      + +

      Using logical combinations you can combine existing definitions, instead of writing 1 big regular expression:

      + +
      Contract C::And[default_mail_regexp, /#{AppConfig.domain}\z/] => nil
      +def send_admin_invite(email)
      + +

      +Contracts On Keyword Arguments

      + +

      ruby 2.0+, but can be used for normal hashes too, when keyword arguments are +not available

      + +

      Lets say you are writing a simple function and require a bunch of keyword arguments:

      + +
      def connect(host, port:, user:, password:)
      + +

      You can of course put Hash contract on it:

      + +
      Contract String, { :port => C::Num, :user => String, :password => String } => Connection
      +def connect(host, port:, user:, password:)
      + +

      But this will not quite work if you want to have a default values:

      + +
      Contract String, { :port => C::Num, :user => String, :password => String } => Connection
      +def connect(host, port: 5000, user:, password:)
      +  # ...
      +end
      +
      +# No value is passed for port
      +connect("example.org", user: "me", password: "none")
      + +

      Results in:

      + +
      ContractError: Contract violation for argument 2 of 2:
      +        Expected: {:port=>Num, :user=>String, :password=>String},
      +        Actual: {:user=>"me", :password=>"none"}
      +        Value guarded in: Object::connect
      +        With Contract: String, Hash => Connection
      +        At: (irb):12
      +
      + +

      This can be fixed with contract { :port => C::Maybe[C::Num], ... }, but that will +allow nil to be passed in, which is not the original intent.

      + +

      So that is where KeywordArgs and Optional contracts jump in:

      + +
      Contract String, C::KeywordArgs[ :port => C::Optional[C::Num], :user => String, :password => String ] => Connection
      +def connect(host, port: 5000, user:, password:)
      + +

      It looks just like the hash contract, but wrapped in KeywordArgs contract. Notice the usage of Optional contract - this way you specify that :port argument is optional. And it will not fail, when you omit this argument, but it will fail when you pass in nil.

      +

      Contracts On Functions

      Lets say you are writing a simple map function:

      -
      def map(arr, func)
      +
      def map(arr, func)

      map takes an array, and a function. Suppose you want to add a contract to this function. You could try this:

      -
      Contract ArrayOf[Any], Proc => ArrayOf[Any]
      +
      Contract C::ArrayOf[C::Any], Proc => C::ArrayOf[C::Any]
       def map(arr, func)

      This says that the second argument should be a Proc. You can call the function like so:

      -
      p map([1, 2, 3], lambda { |x| x + 1 }) # works
      +
      p map([1, 2, 3], lambda { |x| x + 1 }) # works
      -

      But suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the Func contract. Func takes a contract as it's argument, and uses that contract on the function that you pass in.

      +

      But suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the Func contract. Func takes a contract as its argument, and uses that contract on the function that you pass in.

      Here's a map function that requires an array of numbers, and a function that takes a number and returns a number:

      -
      Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]
      +
      Contract C::ArrayOf[C::Num], C::Func[C::Num => C::Num] => C::ArrayOf[C::Num]
       def map(arr, func)
         ret = []
         arr.each do |x|
      @@ -318,12 +460,16 @@ 

      Try this map function with these two examples:

      -
      p map([1, 2, 3], lambda { |x| x + 1 }) # works
      +
      p map([1, 2, 3], lambda { |x| x + 1 }) # works
       p map([1, 2, 3], lambda { |x| "oops" }) # fails, the lambda returns a string.
      +

      The above examples showed a method accepting a Proc as the last argument, but the same contract works on methods that accept a block:

      + +
      def map(arr, &block)
      +

      NOTE: This is not valid:

      -
      Contract ArrayOf[Num], Func => ArrayOf[Num]
      +
      Contract C::ArrayOf[C::Num], C::Func => C::ArrayOf[C::Num]
       def map(arr, &func)

      Here I am using Func without specifying a contract, like Func[Num => Num]. That's not a legal contract. If you just want to validate that the second argument is a proc, use Proc.

      @@ -333,7 +479,7 @@

      Treat the return value as an array. For example, here's a function that returns two numbers:

      -
      Contract Num => [Num, Num]
      +
      Contract C::Num => [C::Num, C::Num]
       def mult(x)
         return x, x+1
       end
      @@ -343,12 +489,12 @@

      If you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a Hash or nil. If a Hash is returned, it contains information about a person. Your contact might look like this:

      -
      Contract String => Or[Hash, nil]
      +
      Contract String => C::Or[Hash, nil]
       def some_func(str)

      You can make your contract more meaningful with a synonym:

      -
      # the synonym
      +
      # the synonym
       Person = Or[Hash, nil]
       
       # use the synonym here
      @@ -375,7 +521,7 @@ 

      A Proc

      -
      Contract lambda { |x| x.is_a? Numeric } => Num
      +
      Contract lambda { |x| x.is_a? Numeric } => C::Num
       def double(x)

      The lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a Numeric. If it is, it returns true. Otherwise it returns false. @@ -386,7 +532,7 @@

      Here's how the Num class is defined. It does exactly what the lambda did in the previous example:

      -
      class Num
      +
      class Num
         def self.valid? val
           val.is_a? Numeric
         end
      @@ -399,7 +545,7 @@ 

      Here's how the Or class is defined:

      -
      class Or < CallableClass
      +
      class Or < CallableClass
         def initialize(*vals)
           @vals = vals
         end
      @@ -416,14 +562,14 @@ 

      This class inherits from CallableClass, which allows us to use [] when using the class:

      -
      Contract Or[Fixnum, Float] => Num
      +
      Contract C::Or[Fixnum, Float] => C::Num
       def double(x)
         2 * x
       end

      Without CallableClass, we would have to use .new instead:

      -
      Contract Or.new(Fixnum, Float) => Num
      +
      Contract C::Or.new(Fixnum, Float) => C::Num
       def double(x)
       # etc
      @@ -441,7 +587,7 @@

      You can customize this message by overriding the to_s method on your class or proc. For example, suppose we overrode Num's to_s method:

      -
      def Num.to_s
      +
      def Num.to_s
         "a number please"
       end
      @@ -459,7 +605,7 @@

      contracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:

      -
      Contract.override_failure_callback do |data|
      +
      Contract.override_failure_callback do |data|
         puts "You had an error"
         puts failure_msg(data)
       end
      @@ -477,6 +623,50 @@

      If your failure callback returns false, the method that the contract is guarding will not be called (the default behaviour).

      +

      +Providing your own custom validators

      + +

      This can be done with Contract.override_validator:

      + +
      # Make contracts accept all RSpec doubles
      +Contract.override_validator(:class) do |contract|
      +  lambda do |arg|
      +    arg.is_a?(RSpec::Mocks::Double) ||
      +      arg.is_a?(contract)
      +  end
      +end
      + +

      The block you provide should always return lambda accepting one argument - validated argument. Block itself accepts contract as an argument.

      + +

      Possible validator overrides:

      + +
        +
      • +override_validator(MyCustomContract) - allows to add some special behaviour for custom contracts,
      • +
      • +override_validator(Proc) - e.g. lambda { true },
      • +
      • +override_validator(Array) - e.g. [C::Num, String],
      • +
      • +override_validator(Hash) - e.g. { :a => C::Num, :b => String },
      • +
      • +override_validator(Range) - e.g. (1..10),
      • +
      • +override_validator(Regexp) - e.g. /foo/,
      • +
      • +override_validator(Contracts::Args) - e.g. C::Args[C::Num],
      • +
      • +override_validator(Contracts::Func) - e.g. C::Func[C::Num => C::Num],
      • +
      • +override_validator(:valid) - allows to override how contracts that respond to :valid? are handled,
      • +
      • +override_validator(:class) - allows to override how class/module contract constants are handled,
      • +
      • +override_validator(:default) - otherwise, raw value contracts.
      • +
      + +

      Default validators can be found here: lib/contracts/validators.rb.

      +

      Disabling contracts

      @@ -489,7 +679,7 @@

      For example, here's a factorial function without method overloading:

      -
      Contract Num => Num
      +
      Contract C::Num => C::Num
       def fact x
         if x == 1
           x
      @@ -500,12 +690,12 @@ 

      Here it is again, re-written with method overloading:

      -
      Contract 1 => 1
      +
      Contract 1 => 1
       def fact x
         x
       end
       
      -Contract Num => Num
      +Contract C::Num => C::Num
       def fact x
         x * fact(x - 1)
       end
      @@ -514,7 +704,7 @@

      This allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:

      -
      Contract lambda{|n| n < 12 } => Ticket
      +
      Contract lambda{|n| n < 12 } => Ticket
       def get_ticket(age)
         ChildTicket.new(age: age)
       end
      @@ -527,18 +717,17 @@ 

      Note that the second get_ticket contract above could have been simplified to:

      -
      Contract Num => Ticket
      +
      Contract C::Num => Ticket

      This is because the first contract eliminated the possibility of age being less than 12. However, the simpler contract is less explicit; you may want to "spell out" the age condition for clarity, especially if the method is overloaded with many contracts.

      Contracts in modules

      -

      To use contracts on module you need to include both Contracts and Contracts::Modules into it:

      +

      Usage is the same as contracts in classes:

      -
      module M
      -  include Contracts
      -  include Contracts::Modules
      +
      module M
      +  include Contracts::Core
       
         Contract String => String
         def self.parse
      @@ -555,14 +744,14 @@ 

      A simple example:

      -
      class MyBirthday < Struct.new(:day, :month)
      -  include Contracts
      +
      class MyBirthday < Struct.new(:day, :month)
      +  include Contracts::Core
         include Contracts::Invariants
       
         invariant(:day) { 1 <= day && day <= 31 }
         invariant(:month) { 1 <= month && month <= 12 }
       
      -  Contract None => Fixnum
      +  Contract C::None => Fixnum
         def silly_next_day!
           self.day += 1
         end
      @@ -573,7 +762,7 @@ 

      If you run it, last line will generate invariant violation:

      -
      ./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)
      +
      ./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)
          Expected: day condition to be true
          Actual: false
          Value guarded in: MyBirthday::silly_next_day!
      @@ -581,6 +770,16 @@ 

      Which means, that after #silly_next_day! all checks specified in invariant statement will be verified, and if at least one fail, then invariant violation error will be raised.

      +

      +Using contracts within your own code

      + +

      contracts.ruby is obviously designed to check method parameters and return values. But if you want to check whether some other data obeys a contract, you can use Contract.valid?(value, contract). For instance:

      + +
      data = parse(user_input)
      +unless Contract.valid?(data, HashOf[String,Nat])
      +  raise UserInputError.new(user_input)
      +end
      +

      Auto-generate documentation using contracts

      diff --git a/params.json b/params.json index c2e88c1..dcb2af8 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Num, Num => Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\n\r\nclass Math\r\n include Contracts\r\n\r\n Contract Num, Num => Num\r\n def self.add(a, b)\r\n a + b\r\n end\r\nend\r\n\r\nputs Math.add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a REPL and want to figure out how a function should be used.\r\n\r\n## Built-in Contracts\r\n\r\n`Num` is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts` module in your class/module.\r\n\r\ncontracts.ruby comes with a lot of built-in contracts, including the following:\r\n\r\n* [`Num`](http://www.rubydoc.info/gems/contracts/Contracts/Num) – checks that the argument is `Numeric`\r\n* [`Pos`](http://www.rubydoc.info/gems/contracts/Contracts/Pos) – checks that the argument is a positive number\r\n* [`Neg`](http://www.rubydoc.info/gems/contracts/Contracts/Neg) – checks that the argument is a negative number\r\n* [`Nat`](http://www.rubydoc.info/gems/contracts/Contracts/Nat) – checks that the argument is a natural number\r\n* [`Bool`](http://www.rubydoc.info/gems/contracts/Contracts/Bool) – checks that the argument is `true` or `false`\r\n* [`Any`](http://www.rubydoc.info/gems/contracts/Contracts/Any) – Passes for any argument. Use when the argument has no constraints.\r\n* [`None`](http://www.rubydoc.info/gems/contracts/Contracts/None) – Fails for any argument. Use when the method takes no arguments.\r\n* [`Or`](http://www.rubydoc.info/gems/contracts/Contracts/Or) – passes if any of the given contracts pass, e.g. `Or[Fixnum, Float]`\r\n* [`Xor`](http://www.rubydoc.info/gems/contracts/Contracts/Xor) – passes if exactly one of the given contracts pass, e.g. `Xor[Fixnum, Float]`\r\n* [`And`](http://www.rubydoc.info/gems/contracts/Contracts/And) – passes if all contracts pass, e.g. `And[Fixnum, Float]`\r\n* [`Not`](http://www.rubydoc.info/gems/contracts/Contracts/Not) – passes if all contracts fail for the given argument, e.g. `Not[nil]`\r\n* [`ArrayOf`](http://www.rubydoc.info/gems/contracts/Contracts/ArrayOf) – checks that the argument is an array, and all elements pass the given contract, e.g. `ArrayOf[Num]`\r\n* [`HashOf`](http://www.rubydoc.info/gems/contracts/Contracts/HashOf) – checks that the argument is a hash, and all keys and values pass the given contract, e.g. `HashOf[Symbol, String]`\r\n* [`Maybe`](http://www.rubydoc.info/gems/contracts/Contracts/Maybe) – passes if the argument is `nil`, or if the given contract passes\r\n* [`RespondTo`](http://www.rubydoc.info/gems/contracts/Contracts/RespondTo) – checks that the argument responds to all of the given methods, e.g. `RespondTo[:password, :credit_card]`\r\n* [`Send`](http://www.rubydoc.info/gems/contracts/Contracts/Send) – checks that all named methods return true, e.g. `Send[:valid?]`\r\n* [`Exactly`](http://www.rubydoc.info/gems/contracts/Contracts/Exactly) – checks that the argument has the given type, not accepting sub-classes, e.g. `Exactly[Numeric]`.\r\n\r\nTo see all the built-in contracts and their full descriptions, check out the [RDoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the built-in contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract ArrayOf[Num] => Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract Args[Num] => Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract HashOf[Symbol, Num] => Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Functions\r\n\r\nLets say you are writing a simple map function:\r\n\r\n```ruby\r\ndef map(arr, func)\r\n```\r\n\r\n`map` takes an array, and a function. Suppose you want to add a contract to this function. You could try this:\r\n\r\n```ruby\r\nContract ArrayOf[Any], Proc => ArrayOf[Any]\r\ndef map(arr, func)\r\n```\r\n\r\nThis says that the second argument should be a `Proc`. You can call the function like so:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\n```\r\n\r\nBut suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the `Func` contract. `Func` takes a contract as it's argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nEarlier, we used `Proc`, which just says \"make sure the second variable is a Proc\". Now we are using `Func[Num => Num]`, which says \"make sure the second variable is a Proc that takes a number and returns a number\". Better!\r\n\r\nTry this map function with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\nNOTE: This is not valid:\r\n\r\n```ruby\r\nContract ArrayOf[Num], Func => ArrayOf[Num]\r\ndef map(arr, &func)\r\n```\r\n\r\nHere I am using `Func` without specifying a contract, like `Func[Num => Num]`. That's not a legal contract. If you just want to validate that the second argument is a proc, use `Proc`.\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract Num => [Num, Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract Or[Fixnum, Float] => Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract Or.new(Fixnum, Float) => Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! This is commonly called \"pattern matching\" in functional programming languages.\r\n\r\nFor example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract Num => Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract Num => Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\nThis allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:\r\n\r\n```ruby\r\nContract lambda{|n| n < 12 } => Ticket\r\ndef get_ticket(age)\r\n ChildTicket.new(age: age)\r\nend\r\n\r\nContract lambda{|n| n >= 12 } => Ticket\r\ndef get_ticket(age)\r\n AdultTicket.new(age: age)\r\nend\r\n\r\n```\r\n\r\nNote that the second `get_ticket` contract above could have been simplified to:\r\n\r\n```ruby\r\nContract Num => Ticket\r\n```\r\n\r\nThis is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to \"spell out\" the age condition for clarity, especially if the method is overloaded with many contracts.\r\n\r\n## Contracts in modules\r\n\r\nTo use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:\r\n\r\n```ruby\r\nmodule M\r\n include Contracts\r\n include Contracts::Modules\r\n\r\n Contract String => String\r\n def self.parse\r\n # do some hard parsing\r\n end\r\nend\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts\r\n include Contracts::Invariants\r\n\r\n invariant(:day) { 1 <= day && day <= 31 }\r\n invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `invariant` statement will be verified, and if at least one fail, then invariant violation error will be raised.\r\n\r\n## Auto-generate documentation using contracts\r\n\r\nIf you are generating documentation for your code with [YARD](http://yardoc.org/), check out [yard-contracts](https://github.com/sfcgeorge/yard-contracts). It will automatically annotate your functions with contracts information. Instead of documenting each parameter for a function yourself, you can just add a contract and yard-contracts will generate the documentation for you!\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"Contracts.ruby","tagline":"Contracts for Ruby","body":"# The contracts.ruby tutorial\r\n\r\n## Introduction\r\n\r\ncontracts.ruby brings code contracts to the Ruby language. Code contracts allow you make some assertions about your code, and then checks them to make sure they hold. This lets you\r\n\r\n- catch bugs faster\r\n- make it very easy to catch certain types of bugs\r\n- make sure that the user gets proper messaging when a bug occurs.\r\n\r\n## Installation\r\n\r\n gem install contracts\r\n\r\n## Basics\r\n\r\nA simple example:\r\n\r\n```ruby\r\nContract Contracts::Num, Contracts::Num => Contracts::Num\r\ndef add(a, b)\r\n a + b\r\nend\r\n```\r\n\r\nHere, the contract is `Contract Num, Num => Num`. This says that the `add` function takes two numbers and returns a number.\r\n\r\nCopy this code into a file and run it:\r\n\r\n```ruby\r\nrequire 'contracts'\r\n\r\nclass Math\r\n include Contracts::Core\r\n\r\n Contract Contracts::Num, Contracts::Num => Contracts::Num\r\n def self.add(a, b)\r\n a + b\r\n end\r\nend\r\n\r\nputs Math.add(1, \"foo\")\r\n```\r\n\r\nYou'll see a detailed error message like so:\r\n\r\n ./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)\r\n Expected: Contracts::Num,\r\n Actual: \"foo\"\r\n Value guarded in: Object::add\r\n With Contract: Contracts::Num, Contracts::Num\r\n At: foo.rb:6\r\n\r\nThat tells you that your contract was violated! `add` expected a `Num`, and got a string (`\"foo\"`) instead.\r\nBy default, an exception is thrown when a contract fails. This can be changed to do whatever you want. More on this later.\r\n\r\nYou can also see the contract for a function with the `functype` method:\r\n\r\n functype(:add)\r\n => \"add :: Num, Num => Num\"\r\n\r\nThis can be useful if you're in a REPL and want to figure out how a function should be used.\r\n\r\n## Built-in Contracts\r\n\r\n`Num` is one of the built-in contracts that contracts.ruby comes with. The built-in contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts::Builtin` module in your class/module.\r\n\r\ncontracts.ruby comes with a lot of built-in contracts, including the following:\r\n\r\n* Basic types\r\n * [`Num`](http://www.rubydoc.info/gems/contracts/Contracts/Num) – checks that the argument is `Numeric`\r\n * [`Pos`](http://www.rubydoc.info/gems/contracts/Contracts/Pos) – checks that the argument is a positive number\r\n * [`Neg`](http://www.rubydoc.info/gems/contracts/Contracts/Neg) – checks that the argument is a negative number\r\n * [`Nat`](http://www.rubydoc.info/gems/contracts/Contracts/Nat) – checks that the argument is a natural number (>= 0)\r\n * [`Bool`](http://www.rubydoc.info/gems/contracts/Contracts/Bool) – checks that the argument is `true` or `false`\r\n * [`Any`](http://www.rubydoc.info/gems/contracts/Contracts/Any) – Passes for any argument. Use when the argument has no constraints.\r\n * [`None`](http://www.rubydoc.info/gems/contracts/Contracts/None) – Fails for any argument. Use when the method takes no arguments.\r\n\r\n* Logical combinations\r\n * [`Maybe`](http://www.rubydoc.info/gems/contracts/Contracts/Maybe) – specifies that a value _may be_ nil, e.g. `Maybe[String]` (equivalent to `Or[String,nil]`)\r\n * [`Or`](http://www.rubydoc.info/gems/contracts/Contracts/Or) – passes if any of the given contracts pass, e.g. `Or[Fixnum, Float]`\r\n * [`Xor`](http://www.rubydoc.info/gems/contracts/Contracts/Xor) – passes if exactly one of the given contracts pass, e.g. `Xor[Fixnum, Float]`\r\n * [`And`](http://www.rubydoc.info/gems/contracts/Contracts/And) – passes if all contracts pass, e.g. `And[Nat, -> (n) { n.even? }]`\r\n * [`Not`](http://www.rubydoc.info/gems/contracts/Contracts/Not) – passes if all contracts fail for the given argument, e.g. `Not[nil]`\r\n\r\n* Collections\r\n * [`ArrayOf`](http://www.rubydoc.info/gems/contracts/Contracts/ArrayOf) – checks that the argument is an array, and all elements pass the given contract, e.g. `ArrayOf[Num]`\r\n * [`SetOf`](http://www.rubydoc.info/gems/contracts/Contracts/SetOf) – checks that the argument is a set, and all elements pass the given contract, e.g. `SetOf[Num]`\r\n * [`HashOf`](http://www.rubydoc.info/gems/contracts/Contracts/HashOf) – checks that the argument is a hash, and all keys and values pass the given contract, e.g. `HashOf[Symbol => String]` or `HashOf[Symbol,String]`\r\n * [`RangeOf`](http://www.rubydoc.info/gems/contracts/Contracts/RangeOf) – checks that the argument is a range whose elements (#first and #last) pass the given contract, e.g. `RangeOf[Date]`\r\n * [`Enum`](http://www.rubydoc.info/gems/contracts/Contracts/Enum) – checks that the argument is part of a given collection of objects, e.g. `Enum[:a, :b, :c]`\r\n\r\n* Keyword arguments\r\n * [`KeywordArgs`](http://www.rubydoc.info/gems/contracts/Contracts/KeywordArgs) – checks that the argument is an options hash, and all required keyword arguments are present, and all values pass their respective contracts, e.g. `KeywordArgs[:number => Num, :description => Optional[String]]`\r\n * [`Optional`](http://www.rubydoc.info/gems/contracts/Contracts/Optional) – checks that the keyword argument is either not present or pass the given contract, can not be used outside of `KeywordArgs` contract, e.g. `Optional[Num]`\r\n\r\n* Duck typing\r\n * [`RespondTo`](http://www.rubydoc.info/gems/contracts/Contracts/RespondTo) – checks that the argument responds to all of the given methods, e.g. `RespondTo[:password, :credit_card]`\r\n * [`Send`](http://www.rubydoc.info/gems/contracts/Contracts/Send) – checks that all named methods return a truthy value, e.g. `Send[:valid?]`\r\n\r\n* Miscellaneous\r\n * [`Exactly`](http://www.rubydoc.info/gems/contracts/Contracts/Exactly) – checks that the argument has the given type, not accepting sub-classes, e.g. `Exactly[Numeric]`.\r\n * [`Eq`](http://www.rubydoc.info/gems/contracts/Contracts/Eq) – checks that the argument is precisely equal to the given value, e.g. `Eq[String]` matches the class `String` and not a string instance.\r\n * [`Func`](http://www.rubydoc.info/gems/contracts/Contracts/Func) – specifies the contract for a proc/lambda e.g. `Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]`. See section \"Contracts On Functions\".\r\n\r\nTo see all the built-in contracts and their full descriptions, check out the [RDoc](http://rubydoc.info/gems/contracts/Contracts).\r\n\r\nIt is recommended to use shortcut for referring builtin contracts:\r\n\r\n```ruby\r\n# define shortcut somewhere at the top level of your codebase:\r\nC = Contracts\r\n\r\n# and use it:\r\nContract C::Maybe[C::Num], String => C::Num\r\n```\r\n\r\nShortcut name should not be necessary `C`, can be anything that you are comfort\r\nwith while typing and anything that does not conflict with libraries you use.\r\n\r\nAll examples after this point assume you have chosen a shortcut as `C::`.\r\n\r\nIf you are sure, that builtin contracts will not nameclash with your own code\r\nand libraries you may use, then you can include all builtin contracts in your\r\nclass/module:\r\n\r\n```ruby\r\nclass Example\r\n include Contracts::Core\r\n include Contracts::Builtin\r\n\r\n Contract Maybe[Num], Or[Float, String] => Bool\r\n def complicated_algorithm(a, b)\r\n # ...\r\n end\r\nend\r\n```\r\n\r\n## More Examples\r\n\r\n### Hello, World\r\n\r\n```ruby\r\nContract String => nil\r\ndef hello(name)\r\n puts \"hello, #{name}!\"\r\nend\r\n```\r\n\r\nYou always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\n### A Double Function\r\n\r\n```ruby\r\nContract C::Or[Fixnum, Float] => C::Or[Fixnum, Float]\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nSometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.\r\nThis introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Fixnum, Float]` is. The longer way to write it would have been:\r\n\r\n```ruby\r\nContract C::Or.new(Fixnum, Float) => C::Or.new(Fixnum, Float)\r\n```\r\n\r\nAll the built-in contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write\r\n\r\n```ruby\r\nContract C::Or[Fixnum, Float] => C::Or[Fixnum, Float]\r\n```\r\n\r\nor\r\n\r\n```ruby\r\nContract C::Or.new(Fixnum, Float) => C::Or.new(Fixnum, Float)\r\n```\r\n\r\nwhichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Fixnum` and `Float`. Use that instance to validate the argument.\r\n\r\n### A Product Function\r\n\r\n```ruby\r\nContract C::ArrayOf[C::Num] => C::Num\r\ndef product(vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis contract uses the `ArrayOf` contract. Here's how `ArrayOf` works: it takes a contract. It expects the argument to be a list. Then it checks every value in that list to see if it satisfies that contract.\r\n\r\n```ruby\r\n# passes\r\nproduct([1, 2, 3, 4])\r\n\r\n# fails\r\nproduct([1, 2, 3, \"foo\"])\r\n```\r\n\r\n### Another Product Function\r\n\r\n```ruby\r\nContract C::Args[C::Num] => C::Num\r\ndef product(*vals)\r\n total = 1\r\n vals.each do |val|\r\n total *= val\r\n end\r\n total\r\nend\r\n```\r\n\r\nThis function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,\r\n\r\n`Args[Num]` means they should all be numbers.\r\n\r\n`Args[Or[Num, String]]` means they should all be numbers or strings.\r\n\r\n`Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).\r\n\r\n### Contracts On Arrays\r\n\r\nIf an array is one of the arguments and you know how many elements it's going to have, you can put a contract on it:\r\n\r\n```ruby\r\n# a function that takes an array of two elements...a person's age and a person's name.\r\nContract [C::Num, String] => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nIf you don't know how many elements it's going to have, use `ArrayOf`.\r\n\r\n### Contracts On Hashes\r\n\r\nHere's a contract that requires a Hash. We can put contracts on each of the keys:\r\n\r\n```ruby\r\n# note the parentheses around the hash; without those you would get a syntax error\r\nContract ({ :age => C::Num, :name => String }) => nil\r\ndef person(data)\r\n p data\r\nend\r\n```\r\n\r\nThen if someone tries to call the function with bad data, it will fail:\r\n\r\n```ruby\r\n# error: age can't be nil!\r\nperson({:name => \"Adit\", :age => nil})\r\n```\r\n\r\nYou don't need to put a contract on every key. So this call would succeed:\r\n\r\n```ruby\r\nperson({:name => \"Adit\", :age => 42, :foo => \"bar\"})\r\n```\r\n\r\neven though we don't specify a type for `:foo`.\r\n\r\nPeruse this contract on the keys and values of a Hash.\r\n\r\n```ruby\r\nContract C::HashOf[Symbol, C::Num] => C::Num\r\ndef give_largest_value(hsh)\r\n hsh.values.max\r\nend\r\n```\r\nWhich you use like so:\r\n```ruby\r\n# succeeds\r\ngive_largest_value(a: 1, b: 2, c: 3) # returns 3\r\n\r\n# fails\r\ngive_largest_value(\"a\" => 1, 2 => 2, c: 3)\r\n```\r\n\r\n### Contracts On Strings\r\n\r\nWhen you want a contract to match not just any string (i.e. `Contract String => nil`), you can use regular expressions:\r\n```ruby\r\nContract /World|Mars/i => nil\r\ndef greet(name)\r\n puts \"Hello #{name}!\"\r\nend\r\n```\r\n\r\nUsing logical combinations you can combine existing definitions, instead of writing 1 big regular expression:\r\n```ruby\r\nContract C::And[default_mail_regexp, /#{AppConfig.domain}\\z/] => nil\r\ndef send_admin_invite(email)\r\n```\r\n\r\n### Contracts On Keyword Arguments\r\n\r\nruby 2.0+, but can be used for normal hashes too, when keyword arguments are\r\nnot available\r\n\r\nLets say you are writing a simple function and require a bunch of keyword arguments:\r\n\r\n```ruby\r\ndef connect(host, port:, user:, password:)\r\n```\r\n\r\nYou can of course put `Hash` contract on it:\r\n\r\n```ruby\r\nContract String, { :port => C::Num, :user => String, :password => String } => Connection\r\ndef connect(host, port:, user:, password:)\r\n```\r\n\r\nBut this will not quite work if you want to have a default values:\r\n\r\n```ruby\r\nContract String, { :port => C::Num, :user => String, :password => String } => Connection\r\ndef connect(host, port: 5000, user:, password:)\r\n # ...\r\nend\r\n\r\n# No value is passed for port\r\nconnect(\"example.org\", user: \"me\", password: \"none\")\r\n```\r\n\r\nResults in:\r\n\r\n```\r\nContractError: Contract violation for argument 2 of 2:\r\n Expected: {:port=>Num, :user=>String, :password=>String},\r\n Actual: {:user=>\"me\", :password=>\"none\"}\r\n Value guarded in: Object::connect\r\n With Contract: String, Hash => Connection\r\n At: (irb):12\r\n```\r\n\r\nThis can be fixed with contract `{ :port => C::Maybe[C::Num], ... }`, but that will\r\nallow `nil` to be passed in, which is not the original intent.\r\n\r\nSo that is where `KeywordArgs` and `Optional` contracts jump in:\r\n\r\n```ruby\r\nContract String, C::KeywordArgs[ :port => C::Optional[C::Num], :user => String, :password => String ] => Connection\r\ndef connect(host, port: 5000, user:, password:)\r\n```\r\n\r\nIt looks just like the hash contract, but wrapped in `KeywordArgs` contract. Notice the usage of `Optional` contract - this way you specify that `:port` argument is optional. And it will not fail, when you omit this argument, but it will fail when you pass in `nil`.\r\n\r\n### Contracts On Functions\r\n\r\nLets say you are writing a simple map function:\r\n\r\n```ruby\r\ndef map(arr, func)\r\n```\r\n\r\n`map` takes an array, and a function. Suppose you want to add a contract to this function. You could try this:\r\n\r\n```ruby\r\nContract C::ArrayOf[C::Any], Proc => C::ArrayOf[C::Any]\r\ndef map(arr, func)\r\n```\r\n\r\nThis says that the second argument should be a `Proc`. You can call the function like so:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\n```\r\n\r\nBut suppose you want to have a contract on the Proc too! Suppose you want to make sure that the Proc returns a number. Use the `Func` contract. `Func` takes a contract as its argument, and uses that contract on the function that you pass in.\r\n\r\nHere's a `map` function that requires an array of numbers, and a function that takes a number and returns a number:\r\n\r\n```ruby\r\nContract C::ArrayOf[C::Num], C::Func[C::Num => C::Num] => C::ArrayOf[C::Num]\r\ndef map(arr, func)\r\n ret = []\r\n arr.each do |x|\r\n ret << func[x]\r\n end\r\n ret\r\nend\r\n```\r\n\r\nEarlier, we used `Proc`, which just says \"make sure the second variable is a Proc\". Now we are using `Func[Num => Num]`, which says \"make sure the second variable is a Proc that takes a number and returns a number\". Better!\r\n\r\nTry this map function with these two examples:\r\n\r\n```ruby\r\np map([1, 2, 3], lambda { |x| x + 1 }) # works\r\np map([1, 2, 3], lambda { |x| \"oops\" }) # fails, the lambda returns a string.\r\n```\r\n\r\nThe above examples showed a method accepting a `Proc` as the last argument, but the same contract works on methods that accept a block:\r\n\r\n```ruby\r\ndef map(arr, &block)\r\n```\r\n\r\nNOTE: This is not valid:\r\n\r\n```ruby\r\nContract C::ArrayOf[C::Num], C::Func => C::ArrayOf[C::Num]\r\ndef map(arr, &func)\r\n```\r\n\r\nHere I am using `Func` without specifying a contract, like `Func[Num => Num]`. That's not a legal contract. If you just want to validate that the second argument is a proc, use `Proc`.\r\n\r\n### Returning Multiple Values\r\nTreat the return value as an array. For example, here's a function that returns two numbers:\r\n\r\n```ruby\r\nContract C::Num => [C::Num, C::Num]\r\ndef mult(x)\r\n return x, x+1\r\nend\r\n```\r\n\r\n## Synonyms For Contracts\r\n\r\nIf you use a contract a lot, it's a good idea to give it a meaningful synonym that tells the reader more about what your code returns. For example, suppose you have many functions that return a `Hash` or `nil`. If a `Hash` is returned, it contains information about a person. Your contact might look like this:\r\n\r\n```ruby\r\nContract String => C::Or[Hash, nil]\r\ndef some_func(str)\r\n```\r\n\r\nYou can make your contract more meaningful with a synonym:\r\n\r\n```ruby\r\n# the synonym\r\nPerson = Or[Hash, nil]\r\n\r\n# use the synonym here\r\nContract String => Person\r\ndef some_func(str)\r\n```\r\n\r\nNow you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code is now cleaner and more clearly says what the function is doing.\r\n\r\n## Defining Your Own Contracts\r\n\r\nContracts are very easy to define. To re-iterate, there are 5 kinds of contracts:\r\n\r\n- the name of a class (like `String` or `Fixnum`)\r\n- a constant (like `nil` or `1`)\r\n- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not\r\n- a class that responds to the `valid?` class method (more on this later)\r\n- an instance of a class that responds to the `valid?` method (more on this later)\r\n\r\nThe first two don't need any extra work to define: you can just use any constant or class name in your contract and it should just work. Here are examples for the rest:\r\n\r\n### A Proc\r\n\r\n```ruby\r\nContract lambda { |x| x.is_a? Numeric } => C::Num\r\ndef double(x)\r\n```\r\n\r\nThe lambda takes one parameter: the argument that is getting passed to the function. It checks to see if it's a `Numeric`. If it is, it returns true. Otherwise it returns false.\r\nIt's not good practice to write a lambda right in your contract...if you find yourself doing it often, write it as a class instead:\r\n\r\n### A Class With `valid?` As a Class Method\r\n\r\nHere's how the `Num` class is defined. It does exactly what the `lambda` did in the previous example:\r\n\r\n```ruby\r\nclass Num\r\n def self.valid? val\r\n val.is_a? Numeric\r\n end\r\nend\r\n```\r\n\r\nThe `valid?` class method takes one parameter: the argument that is getting passed to the function. It returns true or false.\r\n\r\n### A Class With `valid?` As an Instance Method\r\n\r\nHere's how the `Or` class is defined:\r\n\r\n```ruby\r\nclass Or < CallableClass\r\n def initialize(*vals)\r\n @vals = vals\r\n end\r\n\r\n def valid?(val)\r\n @vals.any? do |contract|\r\n res, _ = Contract.valid?(val, contract)\r\n res\r\n end\r\n end\r\nend\r\n```\r\n\r\nThe `Or` contract takes a sequence of contracts, and passes if any of them pass. It uses `Contract.valid?` to validate the value against the contracts.\r\n\r\nThis class inherits from `CallableClass`, which allows us to use `[]` when using the class:\r\n\r\n```ruby\r\nContract C::Or[Fixnum, Float] => C::Num\r\ndef double(x)\r\n 2 * x\r\nend\r\n```\r\n\r\nWithout `CallableClass`, we would have to use `.new` instead:\r\n\r\n```ruby\r\nContract C::Or.new(Fixnum, Float) => C::Num\r\ndef double(x)\r\n# etc\r\n```\r\n\r\nYou can use `CallableClass` in your own contracts to make them callable using `[]`.\r\n\r\n## Customizing Error Messages\r\n\r\nWhen a contract fails, part of the error message prints the contract:\r\n\r\n ...\r\n Expected: Contracts::Num,\r\n ...\r\n\r\nYou can customize this message by overriding the `to_s` method on your class or proc. For example, suppose we overrode `Num`'s `to_s` method:\r\n\r\n```ruby\r\ndef Num.to_s\r\n \"a number please\"\r\nend\r\n```\r\n\r\nNow the error says:\r\n\r\n ...\r\n Expected: a number please,\r\n ...\r\n\r\n## Failure Callbacks\r\n\r\nSupposing you don't want contract failures to become exceptions. You run a popular website, and when there's a contract exception you would rather log it and continue than throw an exception and break your site.\r\n\r\ncontracts.ruby provides a failure callback that gets called when a contract fails. For example, here we log every failure instead of raising an error:\r\n\r\n```ruby\r\nContract.override_failure_callback do |data|\r\n puts \"You had an error\"\r\n puts failure_msg(data)\r\nend\r\n```\r\n\r\n`failure_msg` is a function that prints out information about the failure. Your failure callback gets a hash with the following values:\r\n\r\n {\r\n :arg => the argument to the method,\r\n :contract => the contract that got violated,\r\n :class => the method's class,\r\n :method => the method,\r\n :contracts => the contract object\r\n }\r\n\r\nIf your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).\r\n\r\n## Providing your own custom validators\r\n\r\nThis can be done with `Contract.override_validator`:\r\n\r\n```ruby\r\n# Make contracts accept all RSpec doubles\r\nContract.override_validator(:class) do |contract|\r\n lambda do |arg|\r\n arg.is_a?(RSpec::Mocks::Double) ||\r\n arg.is_a?(contract)\r\n end\r\nend\r\n```\r\n\r\nThe block you provide should always return lambda accepting one argument - validated argument. Block itself accepts contract as an argument.\r\n\r\nPossible validator overrides:\r\n\r\n- `override_validator(MyCustomContract)` - allows to add some special behaviour for custom contracts,\r\n- `override_validator(Proc)` - e.g. `lambda { true }`,\r\n- `override_validator(Array)` - e.g. `[C::Num, String]`,\r\n- `override_validator(Hash)` - e.g. `{ :a => C::Num, :b => String }`,\r\n- `override_validator(Range)` - e.g. `(1..10)`,\r\n- `override_validator(Regexp)` - e.g. `/foo/`,\r\n- `override_validator(Contracts::Args)` - e.g. `C::Args[C::Num]`,\r\n- `override_validator(Contracts::Func)` - e.g. `C::Func[C::Num => C::Num]`,\r\n- `override_validator(:valid)` - allows to override how contracts that respond to `:valid?` are handled,\r\n- `override_validator(:class)` - allows to override how class/module contract constants are handled,\r\n- `override_validator(:default)` - otherwise, raw value contracts.\r\n\r\nDefault validators can be found here: [lib/contracts/validators.rb](https://github.com/egonSchiele/contracts.ruby/blob/master/lib/contracts/validators.rb).\r\n\r\n## Disabling contracts\r\n\r\nIf you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.\r\n\r\n## Method overloading\r\n\r\nYou can use contracts for method overloading! This is commonly called \"pattern matching\" in functional programming languages.\r\n\r\nFor example, here's a factorial function without method overloading:\r\n\r\n```ruby\r\nContract C::Num => C::Num\r\ndef fact x\r\n if x == 1\r\n x\r\n else\r\n x * fact(x - 1)\r\n end\r\nend\r\n```\r\n\r\nHere it is again, re-written with method overloading:\r\n\r\n```ruby\r\nContract 1 => 1\r\ndef fact x\r\n x\r\nend\r\n\r\nContract C::Num => C::Num\r\ndef fact x\r\n x * fact(x - 1)\r\nend\r\n```\r\n\r\nFor an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.\r\n\r\nThis allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:\r\n\r\n```ruby\r\nContract lambda{|n| n < 12 } => Ticket\r\ndef get_ticket(age)\r\n ChildTicket.new(age: age)\r\nend\r\n\r\nContract lambda{|n| n >= 12 } => Ticket\r\ndef get_ticket(age)\r\n AdultTicket.new(age: age)\r\nend\r\n\r\n```\r\n\r\nNote that the second `get_ticket` contract above could have been simplified to:\r\n\r\n```ruby\r\nContract C::Num => Ticket\r\n```\r\n\r\nThis is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to \"spell out\" the age condition for clarity, especially if the method is overloaded with many contracts.\r\n\r\n## Contracts in modules\r\n\r\nUsage is the same as contracts in classes:\r\n\r\n```ruby\r\nmodule M\r\n include Contracts::Core\r\n\r\n Contract String => String\r\n def self.parse\r\n # do some hard parsing\r\n end\r\nend\r\n```\r\n\r\n## Invariants\r\n\r\nInvariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.\r\n\r\n**NOTE**: Only methods with contracts will be affected.\r\n\r\nA simple example:\r\n\r\n```ruby\r\nclass MyBirthday < Struct.new(:day, :month)\r\n include Contracts::Core\r\n include Contracts::Invariants\r\n\r\n invariant(:day) { 1 <= day && day <= 31 }\r\n invariant(:month) { 1 <= month && month <= 12 }\r\n\r\n Contract C::None => Fixnum\r\n def silly_next_day!\r\n self.day += 1\r\n end\r\nend\r\n\r\nbirthday = MyBirthday.new(31, 12)\r\nbirthday.silly_next_day!\r\n```\r\n\r\nIf you run it, last line will generate invariant violation:\r\n\r\n```ruby\r\n./invariant.rb:38:in `failure_callback': Invariant violation: (RuntimeError)\r\n Expected: day condition to be true\r\n Actual: false\r\n Value guarded in: MyBirthday::silly_next_day!\r\n At: main.rb:9\r\n```\r\n\r\nWhich means, that after `#silly_next_day!` all checks specified in `invariant` statement will be verified, and if at least one fail, then invariant violation error will be raised.\r\n\r\n## Using contracts within your own code\r\n\r\ncontracts.ruby is obviously designed to check method parameters and return values. But if you want to check whether some other data obeys a contract, you can use `Contract.valid?(value, contract)`. For instance:\r\n\r\n```ruby\r\ndata = parse(user_input)\r\nunless Contract.valid?(data, HashOf[String,Nat])\r\n raise UserInputError.new(user_input)\r\nend\r\n```\r\n\r\n## Auto-generate documentation using contracts\r\n\r\nIf you are generating documentation for your code with [YARD](http://yardoc.org/), check out [yard-contracts](https://github.com/sfcgeorge/yard-contracts). It will automatically annotate your functions with contracts information. Instead of documenting each parameter for a function yourself, you can just add a contract and yard-contracts will generate the documentation for you!\r\n\r\n## Misc\r\n\r\nPlease submit any bugs [here](https://github.com/egonSchiele/contracts.ruby/issues) and I'll try to get them resolved ASAP!\r\n\r\nSee any mistakes in this tutorial? I try to make it bug-free, but they can creep in. [File an issue](https://github.com/egonSchiele/contracts.ruby/issues).\r\n\r\nIf you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)\r\n\r\nSee the [wiki](https://github.com/egonSchiele/contracts.ruby/wiki) for more info.\r\n\r\nHappy Coding!","google":"UA-32498338-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file