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)