Class: Concurrent::Maybe
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
|
|
|
Instance Chain:
self,
Comparable,
Synchronization::Object,
Synchronization::Volatile,
Synchronization::AbstractObject
|
|
| Inherits: | Concurrent::Synchronization::Object |
| Defined in: | lib/concurrent-ruby/concurrent/maybe.rb |
Overview
A Maybe encapsulates an optional value. A Maybe either contains a value of (represented as Just), or it is empty (represented as Nothing). Using Maybe is a good way to deal with errors or exceptional cases without resorting to drastic measures such as exceptions.
Maybe is a replacement for the use of nil with better type checking.
For compatibility with Concern::Obligation the predicate and accessor methods are aliased as #fulfilled?, #rejected?, #value, and #reason.
Motivation
A common pattern in languages with pattern matching, such as Erlang and Haskell, is to return either a value or an error from a function Consider this Erlang code:
“‘erlang case file:consult(“data.dat”) of
{ok, Terms} -> do_something_useful(Terms);
{error, Reason} -> lager:error(Reason)
end. “‘
In this example the standard library function consult returns a tuple with two elements: an atom (similar to a ruby symbol) and a variable containing ancillary data. On success it returns the atom ok and the data from the file. On failure it returns error and a string with an explanation of the problem. With this pattern there is no ambiguity regarding success or failure. If the file is empty the return value cannot be misinterpreted as an error. And when an error occurs the return value provides useful information.
In Ruby we tend to return nil when an error occurs or else we raise an exception. Both of these idioms are problematic. Returning nil is ambiguous because nil may also be a valid value. It also lacks information pertaining to the nature of the error. Raising an exception is both expensive and usurps the normal flow of control. All of these problems can be solved with the use of a Maybe.
A Maybe is unambiguous with regard to whether or not it contains a value. When Just it contains a value, when Nothing it does not. When Just the value it contains may be nil, which is perfectly valid. When Nothing the reason for the lack of a value is contained as well. The previous Erlang example can be duplicated in Ruby in a principled way by having functions return Maybe objects:
“‘ruby result = MyFileUtils.consult(“data.dat”) # returns a Maybe if result.just?
do_something_useful(result.value) # or result.just
else
logger.error(result.reason) # or result.nothing
end “‘
Constant Summary
-
NONE =
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 111
::Object.new.freeze
Class Attribute Summary
Synchronization::Object - Inherited
Class Method Summary
-
.from(*args) {|args| ... } ⇒ Maybe
Create a new
Maybeusing the given block. -
.just(value) ⇒ Maybe
Create a new
Justwith the given value. -
.nothing(error = '') ⇒ Maybe
Create a new
Nothingwith the given (optional) reason. -
.new(just, nothing) ⇒ Maybe
constructor
private
Create a new
Maybewith the given attributes.
Synchronization::Object - Inherited
| .atomic_attribute?, .atomic_attributes, | |
| .attr_atomic | Creates methods for reading and writing to a instance variable with volatile (Java) semantic as |
| .attr_volatile | Creates methods for reading and writing (as |
| .ensure_safe_initialization_when_final_fields_are_present | For testing purposes, quite slow. |
| .new | Has to be called by children. |
| .safe_initialization!, .define_initialize_atomic_fields | |
Synchronization::AbstractObject - Inherited
Instance Attribute Summary
-
#fulfilled?
readonly
Alias for #just?.
-
#just
(also: #value)
readonly
The value of a
MaybewhenJust. -
#just? ⇒ Boolean
(also: #fulfilled?)
readonly
Is this
MaybeaJust(successfully fulfilled with a value)? -
#nothing
(also: #reason)
readonly
The reason for the
MaybewhenNothing. -
#nothing? ⇒ Boolean
(also: #rejected?)
readonly
Is this
Maybea .nothing (rejected with an exception upon fulfillment)? -
#reason
readonly
Alias for #nothing.
-
#rejected?
readonly
Alias for #nothing?.
-
#value
readonly
Alias for #just.
Instance Method Summary
-
#<=>(other) ⇒ Integer
Comparison operator.
-
#or(other) ⇒ Object
Return either the value of self or the given default value.
Synchronization::Object - Inherited
Synchronization::Volatile - Included
Synchronization::AbstractObject - Inherited
Constructor Details
.new(just, nothing) ⇒ Maybe (private)
Create a new Maybe with the given attributes.
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 224
def initialize(just, nothing) @just = just @nothing = nothing end
Class Method Details
.from(*args) {|args| ... } ⇒ Maybe
Create a new Maybe using the given block.
Runs the given block passing all function arguments to the block as block arguments. If the block runs to completion without raising an exception a new Just is created with the value set to the return value of the block. If the block raises an exception a new Nothing is created with the reason being set to the raised exception.
.just(value) ⇒ Maybe
Create a new Just with the given value.
.nothing(error = '') ⇒ Maybe
Create a new Nothing with the given (optional) reason.
Instance Attribute Details
#fulfilled? (readonly)
Alias for #just?.
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 179
alias :fulfilled? :just?
#just (readonly) Also known as: #value
The value of a Maybe when Just. Will be NONE when Nothing.
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 114
attr_reader :just
#just? ⇒ Boolean (readonly)
Also known as: #fulfilled?
Is this Maybe a Just (successfully fulfilled with a value)?
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 176
def just? ! nothing? end
#nothing (readonly) Also known as: #reason
The reason for the Maybe when Nothing. Will be NONE when Just.
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 117
attr_reader :nothing
#nothing? ⇒ Boolean (readonly)
Also known as: #rejected?
Is this Maybe a .nothing (rejected with an exception upon fulfillment)?
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 184
def nothing? @nothing != NONE end
#reason (readonly)
Alias for #nothing.
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 191
alias :reason :nothing
#rejected? (readonly)
Alias for #nothing?.
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 187
alias :rejected? :nothing?
#value (readonly)
Alias for #just.
# File 'lib/concurrent-ruby/concurrent/maybe.rb', line 189
alias :value :just
Instance Method Details
#<=>(other) ⇒ Integer
Comparison operator.
#or(other) ⇒ Object
Return either the value of self or the given default value.