mirror of
https://github.com/ms-ati/docile
synced 2023-03-27 23:21:52 -04:00
Add entry point that returns block output
This commit is contained in:
parent
4ff2030975
commit
5d59cf33cf
3 changed files with 89 additions and 0 deletions
27
README.md
27
README.md
|
@ -274,6 +274,33 @@ end
|
||||||
|
|
||||||
All set!
|
All set!
|
||||||
|
|
||||||
|
### Accessing the block's return value
|
||||||
|
|
||||||
|
Sometimes you might want to access the return value of your provided block,
|
||||||
|
as opposed to the DSL object itself. In these cases, use
|
||||||
|
`dsl_eval_with_block_return`. It behaves exactly like `dsl_eval`, but returns
|
||||||
|
the output from executing the block, rather than the DSL object.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
arr = []
|
||||||
|
with_array(arr) do
|
||||||
|
push "a"
|
||||||
|
push "b"
|
||||||
|
push "c"
|
||||||
|
length
|
||||||
|
end
|
||||||
|
#=> 3
|
||||||
|
|
||||||
|
arr
|
||||||
|
#=> ["a", "b", "c"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
def with_array(arr=[], &block)
|
||||||
|
Docile.dsl_eval_with_block_return(arr, &block)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
1. Method lookup falls back from the DSL object to the block's context
|
1. Method lookup falls back from the DSL object to the block's context
|
||||||
|
|
|
@ -45,6 +45,45 @@ module Docile
|
||||||
end
|
end
|
||||||
module_function :dsl_eval
|
module_function :dsl_eval
|
||||||
|
|
||||||
|
# Execute a block in the context of an object whose methods represent the
|
||||||
|
# commands in a DSL, and return the block's return value.
|
||||||
|
#
|
||||||
|
# @note Use with an *imperative* DSL (commands modify the context object)
|
||||||
|
#
|
||||||
|
# Use this method to execute an *imperative* DSL, which means that:
|
||||||
|
#
|
||||||
|
# 1. Each command mutates the state of the DSL context object
|
||||||
|
# 2. The return value of each command is ignored
|
||||||
|
# 3. The final return value is the original context object
|
||||||
|
#
|
||||||
|
# @example Use a String as a DSL
|
||||||
|
# Docile.dsl_eval("Hello, world!") do
|
||||||
|
# reverse!
|
||||||
|
# upcase!
|
||||||
|
# first
|
||||||
|
# end
|
||||||
|
# #=> "!"
|
||||||
|
#
|
||||||
|
# @example Use an Array as a DSL
|
||||||
|
# Docile.dsl_eval([]) do
|
||||||
|
# push "a"
|
||||||
|
# push "b"
|
||||||
|
# pop
|
||||||
|
# push "c"
|
||||||
|
# length
|
||||||
|
# end
|
||||||
|
# #=> 2
|
||||||
|
#
|
||||||
|
# @param dsl [Object] context object whose methods make up the DSL
|
||||||
|
# @param args [Array] arguments to be passed to the block
|
||||||
|
# @param block [Proc] the block of DSL commands to be executed against the
|
||||||
|
# `dsl` context object
|
||||||
|
# @return [Object] the return value from executing the block
|
||||||
|
def dsl_eval_with_block_return(dsl, *args, &block)
|
||||||
|
exec_in_proxy_context(dsl, FallbackContextProxy, *args, &block)
|
||||||
|
end
|
||||||
|
module_function :dsl_eval_with_block_return
|
||||||
|
|
||||||
# Execute a block in the context of an immutable object whose methods,
|
# Execute a block in the context of an immutable object whose methods,
|
||||||
# and the methods of their return values, represent the commands in a DSL.
|
# and the methods of their return values, represent the commands in a DSL.
|
||||||
#
|
#
|
||||||
|
|
|
@ -263,6 +263,29 @@ describe Docile do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.dsl_eval_with_block_return' do
|
||||||
|
let(:array) { [] }
|
||||||
|
let!(:result) { execute_dsl_against_array }
|
||||||
|
|
||||||
|
def execute_dsl_against_array
|
||||||
|
Docile.dsl_eval_with_block_return(array) do
|
||||||
|
push 1
|
||||||
|
push 2
|
||||||
|
pop
|
||||||
|
push 3
|
||||||
|
'Return me!'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'executes the block against the DSL context object' do
|
||||||
|
expect(array).to eq([1, 3])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the block's return value" do
|
||||||
|
expect(result).to eq('Return me!')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '.dsl_eval_immutable' do
|
describe '.dsl_eval_immutable' do
|
||||||
|
|
||||||
context 'when DSL context object is a frozen String' do
|
context 'when DSL context object is a frozen String' do
|
||||||
|
|
Loading…
Reference in a new issue