Competition - There must be a better way to .....
[1/5] 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
[2/5] from: ale870::gmail::com at: 24-Nov-2007 15:55
I had the same problem (similar problem) when I created Framework "Laccio".
I solved simply creating a variabile in the external container:
internal-variable: none
ctx1: context [
internal-variable: "A"
]
I used this "trick" to create several instances of the same Layout (View
Layout). See the following real example:
ctx1: context [
myButton: none
myLayout: [
myButton: button "Click me"
]
]
view layout ctx1/myLayout
If you think I'm to the right way, you can donwload my framework from
http://laccio.wordpress.com then take a look to the viewer implementation
(not the controller).
On Nov 24, 2007 5:13 AM, Peter Wood <pwawood-gmail.com> wrote:
> Seeing the great response to previous competitions, I thought that I'd
> start one too.
<<quoted lines omitted: 91>>
> To unsubscribe from the list, just send an email to
> lists at rebol.com with unsubscribe as the subject.
--
//Alessandro
http://sguish.wordpress.com
http://laccio.wordpress.com
[3/5] from: pwawood::gmail::com at: 25-Nov-2007 8:45
Alessandro
I think the problem that you've solved is slightly different to mine. I
need to add words to the context after it has been created as I don't
know what variables will be supplied until the script is running.
Regards
Peter
On Saturday, November 24, 2007, at 10:55 pm, Alessandro Manotti wrote:
[4/5] from: ale870::gmail::com at: 25-Nov-2007 9:55
Now I don't remember the function, but in Rebol you can dynamically get the
variables used in one function. It means you could create a bind at runtime
using such variables.. The problem is in this way you cannot make difference
between locals and globals.
Can you establish a "standard" and, for example, expect that the new dynamic
context may contain a default function (e.g.: called (binder) ) to be called
to get/set bind variables? This is the way that in languages like java use
with "interface" or abstract classes (like a "promise": you simply say that
the new context must contain a specific function(s) ).
On Nov 25, 2007 1:45 AM, Peter Wood <pwawood-gmail.com> wrote:
> Alessandro
> I think the problem that you've solved is slightly different to mine. I
<<quoted lines omitted: 169>>
> To unsubscribe from the list, just send an email to
> lists at rebol.com with unsubscribe as the subject.
--
//Alessandro
http://sguish.wordpress.com
http://laccio.wordpress.com
[5/5] from: pwawood::gmail::com at: 25-Nov-2007 18:56
HI Alessandro
The code that I posted seems to do what I want: it finds new variables in
the code to be tested, adds equivalent words to the context and then binds
the code to be tested to the context for the test code.
I think there must be a better way to do what I want which is why I started
the competition.
As for the function, you may be thinking of first which when applied on a
function gives the argument block; second gives the body of the function.
>> first :append
== [series value /only]
>> second :append
== [
head either only [
insert/only tail series :value
] [
insert tail series :value
]
]
If first is applied to an object, you get a list of the members including
self:
>> a: make object! [
[ b: 1
[ c: 2
[ d: 3
[ ]
>> first a
== [self b c d]
Regards
Peter
On 25/11/2007, Alessandro Manotti <ale870-gmail.com> wrote:
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted