class Docile::FallbackContextProxy

def initialize(receiver, fallback)

Parameters:
  • fallback (Object) -- the fallback proxy target to which any methods
  • receiver (Object) -- the primary proxy target to which all methods
def initialize(receiver, fallback)
  @__receiver__ = receiver
  @__fallback__ = fallback
  # Enables calling DSL methods from helper methods in the block's context
  unless fallback.respond_to?(:method_missing)
    # NOTE: We could switch to {#define_singleton_method} on current Rubies
    singleton_class = (class << fallback; self; end)
    # instrument {#method_missing} on the block's context to fallback to
    # the DSL object. This allows helper methods in the block's context to
    # contain calls to methods on the DSL object.
    singleton_class.
      send(:define_method, :method_missing) do |method, *args, &block|
        m = method.to_sym
        if !NON_FALLBACK_METHODS.member?(m) &&
           !fallback.respond_to?(m) &&
           receiver.respond_to?(m)
          receiver.__send__(method.to_sym, *args, &block)
        else
          super(method, *args, &block)
        end
      end
    if singleton_class.respond_to?(:ruby2_keywords, true)
      singleton_class.send(:ruby2_keywords, :method_missing)
    end
    # instrument a helper method to remove the above instrumentation
    singleton_class.
      send(:define_method, :__docile_undo_fallback__) do
        singleton_class.send(:remove_method, :method_missing)
        singleton_class.send(:remove_method, :__docile_undo_fallback__)
      end
  end
end