README.rdoc in rumonade-0.2.2 vs README.rdoc in rumonade-0.3.0

- old
+ new

@@ -1,10 +1,12 @@ +{<img src="https://secure.travis-ci.org/ms-ati/rumonade.png?branch=master" alt="Build Status" />}[http://travis-ci.org/ms-ati/rumonade] + = Rumonade[https://rubygems.org/gems/rumonade] Project: github[http://github.com/ms-ati/rumonade] -Documentation: rubydoc.info[http://rubydoc.info/gems/rumonade/0.2.1/file/README.rdoc] +Documentation: rubydoc.info[http://rubydoc.info/gems/rumonade/frames] == A Ruby[http://www.ruby-lang.org] Monad[http://en.wikipedia.org/wiki/Monad_(functional_programming)] Library, Inspired by Scala[http://www.scala-lang.org] Are you working in both the Scala[http://www.scala-lang.org] and Ruby[http://www.ruby-lang.org] worlds, and finding that you miss some of the practical benefits of Scala's @@ -26,12 +28,11 @@ idiom will be implemented to turn blocks which might throw exceptions into Option or Either results. If this proves useful (and a good fit for Ruby), then more narrow functional catchers can be implemented as well. == Usage -Using Option, one can transform _possibly_ _nil_ values in a _functional_ fashion, which can increase clarity while -eliminating opportunities for bugs: +==== {Rumonade::Option Option}: handle _possibly_ _nil_ values in a _functional_ fashion: def format_date_in_march(time_or_date_or_nil) Option(time_or_date_or_nil). # wraps possibly-nil value in an Option monad (Some or None) map(&:to_date). # transforms a contained Time value into a Date value select {|d| d.month == 3}. # filters out non-matching Date values (Some becomes None) @@ -45,9 +46,39 @@ format_date_in_march(Time.parse('2011-03-21 12:34')) # => "20110321" Note: * each step of the chained computations above are functionally isolated * the value can notionally _start_ as nil, or _become_ nil during a computation, without effecting any other chained computations + +==== {Rumonade::Either Either}: handle failures ({Rumonade::Left Left}) and successes ({Rumonade::Right Right}) in a _functional_ fashion: + + def find_person(name) + case name + when /Jack/i, /John/i + Right(name.capitalize) + else + Left("No such person: #{name.capitalize}") + end + end + + # success looks like this: + find_person("Jack") + # => Right("Jack") + + # failure looks like this: + find_person("Jill") + # => Left("No such person: Jill") + + # on the 'happy path', we can functionally combine and transform successes: + (find_person("Jack").lift_to_a + find_person("John").lift_to_a).right.map { |*names| names.join(" and ") } + # => Right("Jack and John") + + # while the failure cases are easily handled as well: + (find_person("Jack").lift_to_a + + find_person("John").lift_to_a + + find_person("Jill").lift_to_a + + find_person("Joan").lift_to_a).right.map { |*names| names.join(" and ") } + # => Left("No such person: Jill", "No such person: Joan") (_more_ _examples_ _coming_ _soon_...) == Approach