lib/promise.rb in promise-0.3.0 vs lib/promise.rb in promise-0.3.1

- old
+ new

@@ -15,11 +15,11 @@ # x + 5 # => 15 # class Promise < defined?(BasicObject) ? BasicObject : ::Object NOT_SET = ::Object.new.freeze - instance_methods.each { |m| undef_method m unless m.to_s =~ /__/ } + instance_methods.each { |m| undef_method m unless m =~ /^(__.*|object_id)$/ } ## # Creates a new promise. # # @example Lazily evaluate a database call @@ -27,11 +27,11 @@ # # @yield [] The block to evaluate lazily. # @see Kernel#promise def initialize(&block) if block.arity > 0 - raise ArgumentError, "Cannot store a promise that requires an argument" + ::Kernel.raise ::ArgumentError, "Cannot store a promise that requires an argument" end @block = block @mutex = ::Mutex.new @result = NOT_SET @error = NOT_SET @@ -41,47 +41,54 @@ # Force the evaluation of this promise immediately # # @return [Object] def __force__ @mutex.synchronize do - if !__forced? + if @result.equal?(NOT_SET) && @error.equal?(NOT_SET) begin @result = @block.call rescue ::Exception => e @error = e end end - end unless __forced? + end if @result.equal?(NOT_SET) && @error.equal?(NOT_SET) # BasicObject won't send raise to Kernel @error.equal?(NOT_SET) ? @result : ::Kernel.raise(@error) end alias_method :force, :__force__ ## # Does this promise support the given method? # - # @param [Symbol] - # @return [true, false] - def respond_to?(method) - :__forced?.equal?(method) || :force.equal?(method) || :__force__.equal?(method) || __force__.respond_to?(method) + # @param [Symbol, Boolean] + # @return [Boolean] + def respond_to?(method, include_all=false) + # If the promised object implements marshal_dump, Marshal will use it in + # preference to our _dump, so make sure that doesn't happen. + return false if :marshal_dump.equal?(method) + + :_dump.equal?(method) || # for Marshal + :force.equal?(method) || + :__force__.equal?(method) || + __force__.respond_to?(method, include_all) end ## - # Returns true if klass.equal?(Promise) or the underlying block returns an - # instance of the given klass + # Method used by Marshal to serialize the object. Forces evaluation. # - # @param [Class] - # @return [true, false] - def is_a?(klass) - klass.equal?(::Promise) || __force__.is_a?(klass) + # @param [Integer] limit -- refer to Marshal doc + # @return [Object] + def _dump(limit) + ::Marshal.dump(__force__, limit) end ## - # Returns true if this promise has finished executing + # Method used by Marshal to deserialize the object. # - # @return [true, false] - def __forced? - !(@result.equal?(NOT_SET) && @error.equal?(NOT_SET)) + # @param [Object] + # @return [Promise] + def self._load(obj) + ::Marshal.load(obj) end private def method_missing(method, *args, &block)