Class: Lazy::Promise
- Inherits:
-
Object
- Object
- Lazy::Promise
- Defined in:
- lib/lazy.rb
Overview
A promise is just a magic object that springs to life when it is actually used for the first time, running the provided block and assuming the identity of the resulting object.
This impersonation isn’t perfect – a promise wrapping nil or false will still be considered true by Ruby – but it’s good enough for most purposes. If you do need to unwrap the result object for some reason (e.g. for truth testing or for simple efficiency), you may do so via Kernel.demand.
Formally, a promise is a placeholder for the result of a deferred computation.
Direct Known Subclasses
Constant Summary collapse
- DIVERGES =
create this once here, rather than creating a proc object for every evaluation
lambda { raise DivergenceError.new }
Instance Method Summary collapse
-
#__result__ ⇒ Object
:nodoc:.
-
#initialize(&computation) ⇒ Promise
constructor
:nodoc:.
-
#inspect ⇒ Object
:nodoc:.
- #marshal_dump ⇒ Object
- #marshal_load(str) ⇒ Object
-
#method_missing(*args, &block) ⇒ Object
:nodoc:.
-
#respond_to?(message) ⇒ Boolean
:nodoc:.
Constructor Details
#initialize(&computation) ⇒ Promise
:nodoc:
55 56 57 58 |
# File 'lib/lazy.rb', line 55 def initialize( &computation ) #:nodoc: @mutex = Mutex.new @computation = computation end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(*args, &block) ⇒ Object
:nodoc:
121 122 123 |
# File 'lib/lazy.rb', line 121 def method_missing( *args, &block ) #:nodoc: __result__.__send__( *args, &block ) end |
Instance Method Details
#__result__ ⇒ Object
:nodoc:
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/lazy.rb', line 67 def __result__ #:nodoc: @mutex.synchronize do if @computation raise LazyException.new( @exception ) if @exception computation = @computation @computation = DIVERGES # trap divergence due to over-eager recursion begin @result = Lazy.demand( computation.call( self ) ) @computation = nil rescue DivergenceError raise rescue Exception => exception # handle exceptions @exception = exception raise LazyException.new( @exception ) end end @result end end |
#inspect ⇒ Object
:nodoc:
91 92 93 94 95 96 97 98 99 |
# File 'lib/lazy.rb', line 91 def inspect #:nodoc: @mutex.synchronize do if @computation "#<#{ __class__ } computation=#{ @computation.inspect }>" else @result.inspect end end end |
#marshal_dump ⇒ Object
101 102 103 104 |
# File 'lib/lazy.rb', line 101 def marshal_dump __result__ Marshal.dump( [ @exception, @result ] ) end |
#marshal_load(str) ⇒ Object
106 107 108 109 110 |
# File 'lib/lazy.rb', line 106 def marshal_load( str ) @mutex = Mutex.new ( @exception, @result ) = Marshal.load( str ) @computation = DIVERGES if @exception end |
#respond_to?(message) ⇒ Boolean
:nodoc:
112 113 114 115 116 117 118 119 |
# File 'lib/lazy.rb', line 112 def respond_to?( ) #:nodoc: = .to_sym == :__result__ or == :inspect or == :marshal_dump or == :marshal_load or __result__.respond_to? end |