Class: Functional::Delay
- Inherits:
-
Object
- Object
- Functional::Delay
- Defined in:
- lib/functional/delay.rb
Overview
Lazy evaluation of a block yielding an immutable result. Useful for expensive operations that may never be needed.
When a Delay is created its state is set to pending. The value and reason are both nil. The first time the #value method is called the enclosed opration will be run and the calling thread will block. Other threads attempting to call #value will block as well. Once the operation is complete the value will be set to the result of the operation or the reason will be set to the raised exception, as appropriate. All threads blocked on #value will return. Subsequent calls to #value will immediately return the cached value. The operation will only be run once. This means that any side effects created by the operation will only happen once as well.
Instance Method Summary collapse
-
#fulfilled? ⇒ Boolean
(also: #value?)
Has the delay been fulfilled?.
-
#initialize { ... } ⇒ Delay
constructor
Create a new
Delayin the:pendingstate. -
#pending? ⇒ Boolean
Is delay completion still pending?.
-
#reason ⇒ StandardError
The exception raised when processing the block.
-
#rejected? ⇒ Boolean
(also: #reason?)
Has the delay been rejected?.
-
#state ⇒ Symbol
Current state of block processing.
-
#value ⇒ Object
Return the (possibly memoized) value of the delayed operation.
Constructor Details
#initialize { ... } ⇒ Delay
Create a new Delay in the :pending state.
28 29 30 31 32 33 |
# File 'lib/functional/delay.rb', line 28 def initialize(&block) raise ArgumentError.new('no block given') unless block_given? @mutex = Mutex.new @state = :pending @task = block end |
Instance Method Details
#fulfilled? ⇒ Boolean Also known as: value?
Has the delay been fulfilled?
79 80 81 |
# File 'lib/functional/delay.rb', line 79 def fulfilled? state == :fulfilled end |
#pending? ⇒ Boolean
Is delay completion still pending?
93 94 95 |
# File 'lib/functional/delay.rb', line 93 def pending? state == :pending end |
#reason ⇒ StandardError
The exception raised when processing the block. Returns nil if the operation is still :pending or has been :fulfilled.
49 50 51 52 53 54 |
# File 'lib/functional/delay.rb', line 49 def reason @mutex.lock @reason ensure @mutex.unlock end |
#rejected? ⇒ Boolean Also known as: reason?
Has the delay been rejected?
86 87 88 |
# File 'lib/functional/delay.rb', line 86 def rejected? state == :rejected end |
#state ⇒ Symbol
Current state of block processing.
38 39 40 41 42 43 |
# File 'lib/functional/delay.rb', line 38 def state @mutex.lock @state ensure @mutex.unlock end |
#value ⇒ Object
Return the (possibly memoized) value of the delayed operation.
If the state is :pending then the calling thread will block while the operation is performed. All other threads simultaneously calling #value will block as well. Once the operation is complete (either :fulfilled or :rejected) all waiting threads will unblock and the new value will be returned.
If the state is not :pending when #value is called the (possibly memoized) value will be returned without blocking and without performing the operation again.
69 70 71 72 73 74 75 |
# File 'lib/functional/delay.rb', line 69 def value @mutex.lock execute_task_once @value ensure @mutex.unlock end |