[REBOL] Competition - There must be a better way to .....
From: pwawood::gmail::com at: 24-Nov-2007 12:13
Seeing the great response to previous competitions, I thought that I'd
start one too.
As part of a test framework I'm working on, I want to evaluate the test
code in a separate context to avoid clashes between the code being
tested and the test framework code.
I found it wasn't as easy as simply binding the block to a different
context. I've come up with a method based on adding new words in the
code to be evaluated to the context before binding them. It seems to
work (I haven't tested it extensively yet) but it's complicated and
uses recursion.
I'm sure many of you can come up with simpler and non-recursive
solutions?
My code:
eval-ctx: make object! [
anchor: none
eval: function [code-block [block!]] [
result
][
bind code-block 'anchor
if error? set/any 'result try code-block [
result: disarm result
]
result
]
]
evaluate: function [code-block [block!]] [
words-to-add
find-words-to-add
p
w
][
words-to-add: copy []
find-words-to-add: func [code-block [block!]][
parse code-block [
any [
set w block! (
find-words-to-add w ;; recursive call
)
|
set w set-word! (
if not in eval-ctx to word! w [
insert insert words-to-add reduce w none
]
)
|
'set set w lit-word! (
if not in eval-ctx w [
insert insert words-to-add to set-word! w none
]
)
|
set p path! set w lit-word! (
if 'set = first p [
if not in eval-ctx w [
insert insert words-to-add to set-word! w none
]
]
)
|
skip
]
]
]
find-words-to-add code-block
if words-to-add <> [] [
eval-ctx: make eval-ctx words-to-add
]
eval-ctx/eval code-block
]
A sample:
>> evaluate [test1: "peter"]
[test1: "peter"]
== "peter"
>> test1
** Script Error: test1 has no value
** Near: test1
>> probe eval-ctx
make object! [
anchor: none
eval: func [code-block [block!] /local
result
][
bind code-block 'anchor
if error? set/any 'result try code-block [
result: disarm result
]
result
]
test1: "peter"
]
Regards
Peter