Working Remotely? Thinking about it?

Are you a member of a geographically dispersed team? Are you thinking of working remotely, or hiring remote developers? Wide Teams is my new blog and podcast for distributed teams. Check it out for getting started guides, tips and best practices, news, interviews, screencasts, and more all about working remotely and collaborating with wide-spread teams.

[ANN] fail-fast 1.0.0 Released

2008 November 30

Number two out of three in my weekend releasing spree, I’m happy to announce the availability of “FailFast”:http://fail-fast.rubyforge.org v.1.0.0.


h2. Description

FailFast is a collection of assertion methods intended for lightweight contract checking.

h2. Installing

sudo gem install fail-fast

h2. Synopsis

  def try
    yield
  rescue FailFast::AssertionFailureError
    ""
  end

  include FailFast::Assertions

  try { assert(true) }            # => true
  try { assert(false) }           # => ""
  try { assert(nil) }             # => ""

  # We can check multiple values at once
  try { assert("foo", :bar, 42) } # => 42
  try { assert(1, 2, nil) }       # => ""

  # assert_exists only checks for nil-ness - false is OK.
  try { assert_exists(true) }     # => true
  try { assert_exists(false) }    # => false
  try { assert_exists(nil) }      # => ""

  # check further constraints after verifying the object is non-nil
  try { assert_exists(99) {|n| n > 100 } } # => ""

  # Assert that a collection is non-empty
  try { assert_one_or_more([1]) }         # => [1]
  try { assert_one_or_more(:foo => :bar) } # => {:foo=>:bar}
  try { assert_one_or_more([]) }           # => ""

  # #deny is the opposite of #assert
  try {  deny(true) }             # => ""
  try { deny(false) }             # => false
  try { deny(nil) }               # => nil

  # Assert that an object is hash-like and contains non-nil values for given keys
  h = {:foo => 1, :bar => 2, :baz => nil}
  try { assert_keys(h, :foo, :bar) } # => {:foo=>1, :bar=>2, :baz=>nil}
  try { assert_keys(h, :baz) }       # => ""
  try { assert_keys(h, :buz) }       # => ""

h2. Rationale

Unexpected nils and other bad values will usually bring a Ruby program down eventually, but the actual point of failure might be deep down the call stack and the error message less than revealing. Judicious use of FailFast assertions to check your assumptions can ensures that the program will end as soon as a contract violation is detected, with a stack trace that points directly at the assertion which failed.

One of the primary goals of FailFast is to make assumption-checking declarative. Assumption checking should be simple and concise so that we can get to the meat of a method without getting bogged down in verifications. At the same time, FailFast is lightweight. It is not a metaprogrammed Design-by-Contract DSL. It is a simple set of shorthand methods for validating values.

It is not the intent of FailFast to have specialized assertions for every eventuality. Rather, it seeks to cover a few common cases where there is a potential for significantly increased clarity and declarativeness.

h2. Features

* Fully spec’d/tested.
* In most cases assertions return their last argument. This makes it easy to check values inline. For instance: assert_exists(obj).foo()
* Most assertions can take a block where a further boolean check can be performed. For instance, use assert_exists(x) { x.predicate? } to check first that x is not nil, and then that it satisfies a predicate.
* AssertionFailure derives directly from Exception so that it will never be silently eaten by no-argument catch statements.

h2. Documentation

See the RDoc.


See the “project site”:http://fail-fast.rubyforge.org for more.

Bookmark and Share
Creative Commons License
This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.

Related posts:

  1. Assertive Code
  2. [ANN] alter-ego 1.0.0 Released
  3. First and Rest in Ruby
  4. Hash Transforms in Ruby
  5. Go Fetch
  • I assume AlterEgo 1.0.1 will be refactored to use this, eh? :-)
  • It was already part of AlterEgo, it just needed to be pulled out into its own gem. Next release of AlterEgo will depend on FailFast as well as the forthcoming HookR library which I wrote over the weekend.
blog comments powered by Disqus