Как составить блок кода Rebol для использования с Set (программно)? - PullRequest
0 голосов
/ 16 декабря 2009

Я хочу сделать это:

>> 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 Ответ

1 голос
/ 18 декабря 2009

Вы обнаружили, что круглые скобки не word! s. Они встроены в 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 работать с круглыми скобками немного сложнее, чем с блоками & mdash; они служат двойной обязанностью за приоритет! Интерпретатор считает, что copy () означает, что вы пытаетесь заключить в скобки выражение, результат которого вы хотите скопировать. (

Вы можете избавить себя от некоторых головных болей, создав вещи как блоки, а затем преобразовав их только в последнюю минуту:

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

P.S. Я не хотел отвлекать вас от вопроса, указав, что скобки на самом деле не нужны:

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

Но хорошие новости об этом заключаются в том, что если вы хотите, чтобы парни служили «более высокой цели», в этом случае всегда есть compose

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

Компоновка подобна использованию «шаблонного диалекта», который только уменьшает выражения, заключенные в скобки, оставляя все остальное как есть. Это хороший способ создания кода на примере, но он определенно сталкивается с проблемами, если ваш сгенерированный код уже использует скобки для приоритета! Тем не менее ... показывает, что ваши диалекты могут использовать скобки для любых целей, точно так же, как они могут придавать значение словам.

...