Gem Version Build Status Coverage Status

Ytry

A Scala inspired gem that introduces Trys to Ruby while aiming for an idiomatic API.

Installation

Add this line to your application's Gemfile:

gem 'ytry'

And then execute:

$ bundle

Or install it yourself as:

$ gem install ytry

Basic usage

The Try type represents a computation that may either result in an error, or return a successfully computed value.

If the block passed to Try runs with no errors, then a Success wrapping the computed value is returned.

An instance of Failure wrapping the error is returned otherwise.

require 'ytry'
include Ytry

Try { 1 + 1 } # Success(2)

Try { 1 / 0 } # Failure(#<ZeroDivisionError: divided by 0>)

Success and Failure provide a unified API that lets us express a sequence of tranformations in a fluent way, without error handling cluttering the flow:

def load_and_parse json_file
  Try { File.read(json_file) }
    .map {|content| JSON.parse(content)}
    .select {|table| table.is_a? Array}
    .recover {|e| puts "Recovering from #{e.message}"; []}
end

load_and_parse(nonexisting_file) # prints "Recovering from No such file..." # Success([])

load_and_parse(wrong_format_file) # prints "Recovering from Element not found" # Success([])

load_and_parse(actual_file) # Success([{"id"=>1, "name"=>"Lorenzo", "dob"=>"22/07/1985"}])

Try#map and Try#recover are means to interact with the value wrapped by a Try in a safe way - i.e. with no risk of errors being raised.

Try#select transforms a Success into a Failure when the underlying value does not satisfy the given predicate - i.e. the given block returns false. That can be useful when validating some input.

Try#get_or_else provides a safe way of retrieving the possibly-missing value it contains. It returns the result of the given block when the Try is a Failure. It is equivalent to Try#get when the Try is a Success.

invalid_json = "[\"missing_quote]"

Try { JSON.parse(invalid_json) }
  .get_or_else{ [] } # []

Try { JSON.parse("[]") }
  .get_or_else { fail "this block is ignored"} # []

It is preferable to use Try#get_or_else over Try#get, as #get will raise an error when called on a Failure. It is possible to check for failure via #empty?, but that tipically leads to non-idiomatic code

Why Try?

Using Try instead of rescue blocks can make your software both clearer and safer as it

License

The gem is available as open source under the terms of the MIT License.