-
-
Save x8x/e0af4637838f020e0673f854a9f6e261 to your computer and use it in GitHub Desktop.
. |
You should bind a
to functions' context, which is provided by :f
:
f: func [/local a][a: context [b: context [c: 'ok]] print do bind [a/b/c] :f] f
ok
If you need to load
it for some reason:
f: func [/local a][a: context [b: context [c: 'ok]] print do bind reduce [load {a/b/c}] :f] f
ok
@toomasv Oh well! That works! Thank you! Guess you win the bounty! Please send me your address on Gitter, so I can transfer the REDs!
..btw, always impressed by your Red productivity!! 👍
Now for some details about how/why that works:
- magic
:f
, when defining functionf
, the body block is just that, ablock!
not executed yet, hence no complain about:f
not being defined yet. While when callingf
,:f
gets its value from the global space, where functionf
is defined. Correct? - Why is that not the same as
bind [] 'a
? Binding to aword!
should execute theblock!
in the context where thatword!
is defined, which in this case would be thef
function body. - Why
do load
, inside the function body, execute in the global space and I need to bind it in the first place?
Still curious about Rebol/Red different behaviours, is that wanted, enhancement, regression?
For reference, this doesn't work in Rebol:
f: func [/local a][a: context [b: context [c: 'ok]] print do bind reduce [load {a/b/c}] :f] f
** Script Error: bind expected known-word argument of type: any-word object port
** Where: f
** Near: print do bind reduce [load "a/b/c"]
@x8x I can't answer all the questions, as I don't know the implementation internals of Red, but I think you are correct on first point.
About the third point, I think it is because the a
resulting from loading the string is bound to default global context. I may hypothesize that a
-s in function's body are bound to local context at definition time, but loading happens in runtime, and a
resulting from loading in runtime is not bound to functions context.
BTW, in my first snippet bind
isn't needed actually, because a
is bound in this case:
f: func [/local a][a: context [b: context [c: 'ok]] print do [a/b/c]] f
; or
f: func [/local a][a: context [b: context [c: 'ok]] print reduce 'a/b/c] f
; or
f: func [/local a][a: context [b: context [c: 'ok]] print a/b/c] f
ok
1) This doesn't work, path is looking for 'a in global space
Why? I wrongly assumed that
do
would execute in the current context which in this case would be inside the function wherea
is defined. Explanation welcome!Rebol:
Red:
2) Works in Rebol, Red returns path instead
Rebol:
Red:
3) Same as previous one, works in Rebol, Red returns path instead
Rebol:
Red:
Any better solution in Rebol than 2 and 3?
4) Note that in Red, even in global space it returns the path instead of the value
This is the same example @dockimbel provided here for Rebol:
https://stackoverflow.com/questions/15093642/how-do-i-pick-elements-from-a-block-using-a-string-in-rebol
Thought, in Red, doing without loading does work, why?
Rebol:
Red:
5) This is wired
Red:
6) Why does this returns false?
Red:
Conclusion: I couldn't find a way to solve this inside a function in Red. 300RED for who does find a solution in Red interpreted and not in global space! (valid until 2018/08/10 UTC) 😃