2011-12-06 18:51:56 +00:00
|
|
|
require "docile/version"
|
2011-12-06 20:05:31 +00:00
|
|
|
require "docile/fallback_context_proxy"
|
2013-07-28 23:22:45 +00:00
|
|
|
require "docile/chaining_fallback_context_proxy"
|
2011-12-06 18:51:56 +00:00
|
|
|
|
2013-07-28 20:24:39 +00:00
|
|
|
# Docile keeps your Ruby DSLs tame and well-behaved
|
|
|
|
# @see http://ms-ati.github.com/docile/
|
2011-12-06 18:51:56 +00:00
|
|
|
module Docile
|
2013-07-28 20:24:39 +00:00
|
|
|
# Execute a block in the context of an object whose methods represent the
|
|
|
|
# commands in a DSL.
|
2011-12-06 19:46:46 +00:00
|
|
|
#
|
2013-07-28 20:24:39 +00:00
|
|
|
# @note Use with an *imperative* DSL (commands modify the context object)
|
2011-12-06 23:46:14 +00:00
|
|
|
#
|
2013-07-28 20:24:39 +00:00
|
|
|
# Use this method to execute an *imperative* DSL, which means that:
|
2011-12-06 19:46:46 +00:00
|
|
|
#
|
2013-07-28 20:24:39 +00:00
|
|
|
# 1. each command mutates the state of the DSL context object
|
|
|
|
# 2. the return values of the commands are ignored
|
|
|
|
#
|
|
|
|
# @example Use a String as a DSL
|
|
|
|
# Docile.dsl_eval("Hello, world!") do
|
|
|
|
# reverse!
|
|
|
|
# upcase!
|
|
|
|
# end
|
|
|
|
# #=> "!DLROW ,OLLEH"
|
|
|
|
#
|
|
|
|
# @example Use an Array as a DSL
|
|
|
|
# Docile.dsl_eval([]) do
|
|
|
|
# push 1
|
|
|
|
# push 2
|
|
|
|
# pop
|
|
|
|
# push 3
|
|
|
|
# end
|
|
|
|
# #=> [1, 3]
|
|
|
|
#
|
|
|
|
# @param dsl [Object] context object whose methods make up the DSL
|
2013-04-01 20:40:26 +00:00
|
|
|
# @param args [Array] arguments to be passed to the block
|
2013-07-28 20:24:39 +00:00
|
|
|
# @yield the block of DSL commands to be executed against the
|
|
|
|
# `dsl` context object
|
|
|
|
# @return [Object] the `dsl` context object after executing the block
|
2013-04-01 03:27:12 +00:00
|
|
|
def dsl_eval(dsl, *args, &block)
|
2013-07-28 23:36:03 +00:00
|
|
|
exec_in_proxy_context(dsl, FallbackContextProxy, *args, &block)
|
2011-12-06 19:46:46 +00:00
|
|
|
dsl
|
|
|
|
end
|
|
|
|
module_function :dsl_eval
|
2013-07-28 23:22:45 +00:00
|
|
|
|
|
|
|
def dsl_eval_immutable(dsl, *args, &block)
|
2013-07-28 23:36:03 +00:00
|
|
|
exec_in_proxy_context(dsl, ChainingFallbackContextProxy, *args, &block)
|
|
|
|
end
|
|
|
|
module_function :dsl_eval_immutable
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def exec_in_proxy_context(dsl, proxy_type, *args, &block)
|
2013-07-28 23:22:45 +00:00
|
|
|
block_context = eval("self", block.binding)
|
2013-07-28 23:36:03 +00:00
|
|
|
proxy_context = proxy_type.new(dsl, proxy_type.new(dsl, block_context))
|
2013-07-28 23:22:45 +00:00
|
|
|
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
|
2013-07-28 23:36:03 +00:00
|
|
|
module_function :exec_in_proxy_context
|
2011-12-06 18:51:56 +00:00
|
|
|
end
|