def set_deferred_status(status, *args)
      cancel_timeout
      @errbacks ||= nil
      @callbacks ||= nil
      @deferred_status = status
      @deferred_args = args
      case @deferred_status
      when :succeeded
        if @callbacks
          while cb = @callbacks.pop
            cb.call(*@deferred_args)
          end
        end
        @errbacks.clear if @errbacks
      when :failed
        if @errbacks
          while eb = @errbacks.pop
            eb.call(*@deferred_args)
          end
        end
        @callbacks.clear if @callbacks
      end
    end
def set_deferred_status(status, *args)
      cancel_timeout
      @errbacks ||= nil
      @callbacks ||= nil
      @deferred_status = status
      @deferred_args = args
      case @deferred_status
      when :succeeded
        if @callbacks
          while cb = @callbacks.pop
            cb.call(*@deferred_args)
          end
        end
        @errbacks.clear if @errbacks
      when :failed
        if @errbacks
          while eb = @errbacks.pop
            eb.call(*@deferred_args)
          end
        end
        @callbacks.clear if @callbacks
      end
    end
Sets the "disposition" (status) of the Deferrable object. See also the large set of
 sugarings for this method.
 Note that if you call this method without arguments,
 no arguments will be passed to the callback/errback.
 If the user has coded these with arguments, then the
 user code will throw an argument exception.
 Implementors of deferrable classes <b>must</b>
 document the arguments they will supply to user callbacks.

 OBSERVE SOMETHING VERY SPECIAL here: you may call this method even
 on the INSIDE of a callback. This is very useful when a previously-registered
 callback wants to change the parameters that will be passed to subsequently-registered
 ones.

 You may give either :succeeded or :failed as the status argument.

 If you pass :succeeded, then all of the blocks passed to the object using the #callback
 method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks
 passed to the object using #errback will be discarded.

 If you pass :failed, then all of the blocks passed to the object using the #errback
 method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks
 passed to the object using # callback will be discarded.

 If you pass any arguments to #set_deferred_status in addition to the status argument,
 they will be passed as arguments to any callbacks or errbacks that are executed.
 It's your responsibility to ensure that the argument lists specified in your callbacks and
 errbacks match the arguments given in calls to #set_deferred_status, otherwise Ruby will raise
 an ArgumentError.

--
 We're shifting callbacks off and discarding them as we execute them.
 This is valid because by definition callbacks are executed no more than
 once. It also has the magic effect of permitting recursive calls, which
 means that a callback can call #set_deferred_status and change the parameters
 that will be sent to subsequent callbacks down the chain.

 Changed @callbacks and @errbacks from push/shift to unshift/pop, per suggestion
 by Kirk Haines, to work around the memory leak bug that still exists in many Ruby
 versions.

 Changed 15Sep07: after processing callbacks or errbacks, CLEAR the other set of
 handlers. This gets us a little closer to the behavior of Twisted's "deferred,"
 which only allows status to be set once. Prior to making this change, it was possible
 to "succeed" a Deferrable (triggering its callbacks), and then immediately "fail" it,
 triggering its errbacks! That is clearly undesirable, but it's just as undesirable
 to raise an exception is status is set more than once on a Deferrable. The latter
 behavior would invalidate the idiom of resetting arguments by setting status from
 within a callback or errback, but more seriously it would cause spurious errors
 if a Deferrable was timed out and then an attempt was made to succeed it. See the
 comments under the new method #timeout.