如何编写一个与Set(编程)一起使用的Rebol代码块?

时间:2009-12-16 15:00:59

标签: rebol

我想这样做:

>> SET [a b] reduce [(ask "a: ") (ask "b: ")]
a: 1
b: 2
== ["1" "2"]
>>

编程:

args: [a b]
block: copy []
foreach arg args [
  append block to-word "("
  append block 'ask
  append block rejoin [arg ": "]
  append block to-word ")"
]
set args reduce block

但是我收到了这个错误:

>>     foreach arg args [
[          append block to-word "("
[          append block 'ask
[          append block rejoin [arg ": "]
[          append block to-word ")"
[        ]
== [( ask "a: " ) ( ask "b: " )]
>>    set args reduce block
** Script Error: ( has no value
** Near: ( ask "a: " ) (
>>

1 个答案:

答案 0 :(得分:1)

您发现的是括号不是word!。它们内置于Rebol,解析器确保它们与您匹配 - 就像block!一样。

这是一件好事 - 否则系统周围的所有代码都会处理()))()不匹配。你已经从那痛苦中得救了!但是如果你想要,那么你可以在自己的方言中重新发挥这种痛苦,并使用像BEGIN和END这样的词,而不是利用永远有用的paren!。 :P

这是代码的极简主义补丁:

args: [a b]
block: copy []
foreach arg args [
   p: to-paren []
   append/only block p
   append p 'ask
   append p rejoin [arg ": "]
]
set args reduce block

请注意,您无法撰写copy ()。一般来说,括号在do方言中使用比使用方块有点棘手 - 它们为优先级提供双重任务!解释器认为copy ()意味着您正在尝试用括号表示要复制结果的表达式。 :(

你可以通过构建块来构建一些令人头疼的问题,然后只在最后一刻转换它们:

>> to-paren [ask "a: "]
== (ask "a: ")

P.S。我不想通过指出括号实际上没有必要来分散你的问题:

>> SET [a b] reduce [ask "a: " ask "b: "]

但有关这方面的好消息是,如果你愿意让parens在这种情况下服务于“更高目的”,那么总是compose

args: [a b]
block: copy []
foreach arg args [
    append block compose [ask (rejoin [arg ": "])]
]
set args reduce block

组合就像使用“模板化方言”,它只会减少parens中包含的表达式,而将其他所有内容保留为原样。这是通过示例创建代码的好方法,但如果生成的代码已经使用括号作为优先级,那肯定会遇到麻烦!仍然......表明你的方言可以将括号用于任何目的,就像它们可以赋予词语意义一样。