Refactor #exec_in_proxy_context into private module Execution

This commit is contained in:
Marc Siegel 2013-07-29 00:06:43 -04:00
parent 62de806d24
commit d36dfa8b21
2 changed files with 37 additions and 31 deletions

View File

@ -1,9 +1,12 @@
require "docile/version"
require "docile/execution"
require "docile/fallback_context_proxy"
require "docile/chaining_fallback_context_proxy"
# Docile keeps your Ruby DSLs tame and well-behaved
module Docile
extend Execution
# Execute a block in the context of an object whose methods represent the
# commands in a DSL.
#
@ -78,35 +81,4 @@ module Docile
exec_in_proxy_context(dsl, ChainingFallbackContextProxy, *args, &block)
end
module_function :dsl_eval_immutable
private
# @api private
#
# Execute a block in the context of an object whose methods represent the
# commands in a DSL, using a specific proxy class.
#
# @param dsl [Object] context object whose methods make up the
# (initial) DSL
# @param proxy_type [Class] class to instantiate as the proxy context
# @param args [Array] arguments to be passed to the block
# @yield the block of DSL commands to be executed
# @return [Object] the return value of the block
def exec_in_proxy_context(dsl, proxy_type, *args, &block)
block_context = eval("self", block.binding)
proxy_context = proxy_type.new(dsl, 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
block_context.instance_variables.each do |ivar|
value_from_dsl_proxy = proxy_context.instance_variable_get(ivar)
block_context.instance_variable_set(ivar, value_from_dsl_proxy)
end
end
end
module_function :exec_in_proxy_context
end

34
lib/docile/execution.rb Normal file
View File

@ -0,0 +1,34 @@
module Docile
# @api private
#
# A namespace for functions relating to the execution of a block agsinst a
# proxy object.
module Execution
# Execute a block in the context of an object whose methods represent the
# commands in a DSL, using a specific proxy class.
#
# @param dsl [Object] context object whose methods make up the
# (initial) DSL
# @param proxy_type [Class] class to instantiate as the proxy context
# @param args [Array] arguments to be passed to the block
# @yield the block of DSL commands to be executed
# @return [Object] the return value of the block
def exec_in_proxy_context(dsl, proxy_type, *args, &block)
block_context = eval("self", block.binding)
proxy_context = proxy_type.new(dsl, 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
block_context.instance_variables.each do |ivar|
value_from_dsl_proxy = proxy_context.instance_variable_get(ivar)
block_context.instance_variable_set(ivar, value_from_dsl_proxy)
end
end
end
module_function :exec_in_proxy_context
end
end