diff --git a/lib/docile.rb b/lib/docile.rb index 5dafd0c..21e5a89 100644 --- a/lib/docile.rb +++ b/lib/docile.rb @@ -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 diff --git a/lib/docile/execution.rb b/lib/docile/execution.rb new file mode 100644 index 0000000..85c1d12 --- /dev/null +++ b/lib/docile/execution.rb @@ -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 \ No newline at end of file