class Rumonade::Option
Represents optional values. Instances of Option
are either an instance of Some
or the object None.
The most idiomatic way to use an Option
instance is to treat it as a collection or monad and use map, flat_map, select, or each:
name = Option(params[:name]) upper = name.map(&:strip).select { |s| s.length != 0 }.map(&:upcase) puts upper.get_or_else("")
Note that this is equivalent to
# TODO: IMPLEMENT FOR COMPREHENSIONS # see http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield val upper = for { name <- Option(params[:name]) trimmed <- Some(name.strip) upper <- Some(trimmed.upcase) if trimmed.length != 0 } yield upper puts upper.get_or_else("")
Because of how for comprehension works, if None is returned from params#[], the entire expression results in None This allows for sophisticated chaining of Option
values without having to check for the existence of a value.
A less-idiomatic way to use Option
values is via direct comparison:
name_opt = params[:name] case name_opt when Some puts name_opt.get.strip.upcase when None puts "No name value" end
@abstract
Public Class Methods
@return [Option] Returns the empty Option
# File lib/rumonade/option.rb, line 47 def empty None end
# File lib/rumonade/option.rb, line 52 def initialize raise(TypeError, "class Option is abstract; cannot be instantiated") if self.class == Option end
@return [Option] Returns an Option
containing the given value
# File lib/rumonade/option.rb, line 42 def unit(value) Rumonade.Some(value) end
Public Instance Methods
Returns None if None, or the result of executing the given block or lambda on the contents if Some
# File lib/rumonade/option.rb, line 58 def bind(lam = nil, &blk) empty? ? self : (lam || blk).call(value) end
@return [Boolean] Returns true
if None
, false
if Some
# File lib/rumonade/option.rb, line 65 def empty? raise(NotImplementedError) end
Returns contents if Some
, or raises NoSuchElementError
if None
# File lib/rumonade/option.rb, line 70 def get if !empty? then value else raise NoSuchElementError end end
Returns contents if Some
, or given value or result of given block or lambda if None
# File lib/rumonade/option.rb, line 75 def get_or_else(val_or_lam = nil, &blk) v_or_f = val_or_lam || blk if !empty? then value else (v_or_f.respond_to?(:call) ? v_or_f.call : v_or_f) end end
Returns contents if Some
, or nil
if None
# File lib/rumonade/option.rb, line 81 def or_nil get_or_else(nil) end