The Maybe monad for Ruby
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib Require the core of Maybe when loading `core_ext` so you don't need t… Jun 26, 2012
test Adds tests Jun 25, 2012
.document Initial commit to maybe. Jan 22, 2010
.gitignore Ignore Rubinius files Nov 23, 2010
LICENSE Update LICENSE Jan 1, 2018 Update Jan 1, 2018
VERSION Version bump to 1.1.0 Jun 25, 2012


A library for treating nil and non-nil objects in a similar manner. Technically speaking, Maybe is an implemenation of the maybe monad.


The Maybe class wraps any value (nil or non-nil) and lets you treat it as non-nil.

require "maybe"
"hello".upcase                         #=> "HELLO"
nil.upcase                             #=> NoMethodError: undefined method `upcase' for nil:NilClass"hello").upcase.__value__    #=> "HELLO"        #=> nil

You can also use the method Maybe for convenience. The following are equivalent:"hello").__value__           #=> "hello"
Maybe("hello").__value__               #=> "hello"

You can also optionally patch Object to include a #maybe method:

require "maybe/core_ext"
"hello".maybe.upcase                   #=> "HELLO"

When you call with a value, that value is wrapped in a Maybe object. Whenever you call methods on that object, it does a simple check: if the wrapped value is nil, then it returns another Maybe object that wraps nil. If the wrapped object is not nil, it calls the method on that object, then wraps it back up in a Maybe object.

This is especially handy for long chains of method calls, any of which could return nil.

# foo, bar, and/or baz could return nil, but this will still work

Here's a real world example. Instead of writing this:

if(customer && customer.order &&
  # ... do something with customer

just write this:

  # ... do something with customer

If your wrapped object does not have a #value method, you can call

instead of


require "maybe""10")                    #=> A Maybe object, wrapping "10""10").to_i               #=> A Maybe object, wrapping 10"10").to_i.__value__     #=> 10                     #=> A Maybe object, wrapping nil                #=> A Maybe object, still wrapping nil      #=> nil

Related Reading

Note on Patches/Pull Requests

  • Fork the project.
  • Make your feature addition or bug fix.
  • Add tests for it. This is important so I don't break it in a future version unintentionally.
  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
  • Send me a pull request. Bonus points for topic branches.


Copyright (c) 2009-2018 Ben Brinckerhoff. See LICENSE for details.