作为一般观点:将字符串转换为 WORD!s (eg to-word "foo"
)很容易。但是,很难神奇地制作那个单词!参考绑定到“你的意思的变量”。这样做的狡猾原因与没有范围有关。看:
是否有关于 Rebol 和 Red 中定义范围的总体解释
因此,无论如何,您要尝试做的事情都会有点狡猾。有更好的方法。但是为了避免不问问题,我将解释这里发生的事情以及如何以您尝试的方式解决它。
更正版本仅用于教学目的。请以另一种方式进行。
compose rejoin [namelist/:i "f/text"]
REJOIN 应用于块,并合并内容,结果类型松散地基于第一个元素。 (这是一个有问题的操作,但历史上在 Rebol 代码中很流行。)
因为namelist/:i
是一个字符串,所以您的 REJOIN 将生成一个字符串......并且这个字符串最终将被传递给 COMPOSE。但是 COMPOSE 旨在应用于 BLOCK!s...并在其中搜索带括号的组,评估它们,同时不理会其余代码。这是一种块模板系统,对其他类型的输入没有影响......所以你会得到相同的字符串。
因此,TO-SET-PATH 被输入了一个字符串!(例如“var1f/text”)。我什至不知道路径转换接受字符串。我发现此操作的行为令人费解,因为它显然会加载字符串,然后使其成为长度为 1 SET-PATH! 的奇异元素。
>> p: to-set-path "foo/bar"
== foo/bar: ;-- huh? really, did that work?
>> type? p
== set-path! ;-- ok, good, I guess.
>> length? p
== 1 ;-- wait, what?
>> type? first p
== path! ;-- a PATH! inside a SET-PATH!...?
>> length? first p
== 2
>> type? first first p
== word!
>> foo: 10
>> get first first p
== 10 ;-- well, at least it's bound
那不是那种 SET-PATH!你要; 你想要一个 SET-PATH!有2个字!元素。转换一个块!到 SET-PATH!将是这样做的一种方式。
to-set-path compose [(load rejoin [namelist/:i "f"]) text]
现在我们看到 COMPOSE 被正确使用了,它会在括号内运行评估,并且不理会这个text
词。这会生成一个包含 2 个元素的块,可以轻松地将其转换为 SET-PATH!。我使用 LOAD 而不是 TO-WORD 来处理连接到纯单词转换无法做到的实际变量的一些“魔力”。但这只是一种解决方法——不是确定的事情,而且并不总是问题的答案。
但是产生一个 SET-PATH!并不意味着它运行。如果我说:
s: to-set-word "x"
probe type? s
没有设置字!被执行,它只是生成。在这种情况下,存储在变量 s 中。但是如果我没有将它存储在一个变量中,那么评估产品就会被丢弃......如果我写1 + 1 print "hi"
. 要执行 SET-PATH!,您需要将它放在一个上下文中,它将被组合成源代码并进行评估。
(注意:Ren-C 有一个称为 EVAL 的原语,它可以即时执行此操作,例如eval (quote x:) 10
将 10 分配给 x。)
但在 Red 中,您需要执行以下操作:
namelist: ["var1" "var2"]
var1: 5
var2: 10
process: [
repeat i length? namelist [
do probe compose [
(to-set-path compose [(load rejoin [namelist/:i "f"]) text])
to-string
(load namelist/:i)
]
]
]
lay: layout [
text "Values to appear here: "
var1f: field "a"
var2f: field "b"
button "Click" [do process]
]
view lay
现在您的外部 COMPOSE 正在构建一个 3 元素块,其中第一个元素将是 SET-PATH!,第二个元素是 WORD!这实际上是单独将您的整数转换为字符串,第三个是单词!将被评估为相关的整数。该块的 DO 将具有分配效果。
我把你to-word namelist/:i
改成load namelist/:i
. 同样,出于我提到的原因...... TO-WORD 本身并没有“绑定”。
我在那里留下了一个 PROBE,这样你就可以看到构建和执行的内容:
[var1f/text: to-string var1]
[var2f/text: to-string var2]
PROBE 是一个非常有用的工具,它输出它的参数但也传递它。您可以在代码中的各个点插入它,以更好地了解正在发生的事情。
(注意:如果您想知道为什么我不建议编写仅适用于 SET-PATH 的窄 EVAL-2 辅助操作!,那是因为这样的东西以更好的名称存在。它称为 SET。set (quote x:) 10
然后尝试print x
。在事实上,这就是你真正想做的事情的变体......obj: make object! [a: 10]
然后......正如我所说set (in obj 'a) 20
,print obj/a
有很多更好的方法可以去做你正在做的事情,但我试图继续专注于做这件事 -你在尝试的方式。)