module Docile::Execution

def exec_in_proxy_context(dsl, proxy_type, *args, &block)

Returns:
  • (Object) - the return value of the block

Parameters:
  • block (Proc) -- the block of DSL commands to be executed
  • args (Array) -- arguments to be passed to the block
  • proxy_type (FallbackContextProxy, ChainingFallbackContextProxy) --
  • dsl (Object) -- context object whose methods make up the
def exec_in_proxy_context(dsl, proxy_type, *args, &block)
  block_context = eval("self", block.binding) # rubocop:disable Style/EvalWithLocation
  # Use #equal? to test strict object identity (assuming that this dictum
  # from the Ruby docs holds: "[u]nlike ==, the equal? method should never
  # be overridden by subclasses as it is used to determine object
  # identity")
  return dsl.instance_exec(*args, &block) if dsl.equal?(block_context)
  proxy_context = proxy_type.new(dsl, block_context)
  begin
    block_context.instance_variables.each do |ivar|
      value_from_block = block_context.instance_variable_get(ivar)
      proxy_context.instance_variable_set(ivar, value_from_block)
    end
    proxy_context.instance_exec(*args, &block)
  ensure
    if block_context.respond_to?(:__docile_undo_fallback__)
      block_context.send(:__docile_undo_fallback__)
    end
    block_context.instance_variables.each do |ivar|
      next unless proxy_context.instance_variables.include?(ivar)
      value_from_dsl_proxy = proxy_context.instance_variable_get(ivar)
      block_context.instance_variable_set(ivar, value_from_dsl_proxy)
    end
  end
end