English 中文(简体)
How to compose a Rebol block of code to be used with Set (Programmatically)?
原标题:
  • 时间:2009-12-16 15:00:58
  •  标签:
  • rebol

I want to do this:

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

Programmatically:

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

But I get this error:

>>     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: " ) (
>>
最佳回答

What you ve discovered is that parentheses are not word!s. They are built-in to Rebol, and the parser makes sure they match up for you—just like block! does.

This is a good thing—otherwise all around the system would be code handling the ()))() mismatches. You ve been saved from that pain! But if you want then you can reinvent this pain in your own dialects, and use words like BEGIN and END instead of leveraging the ever-helpful paren!. :P

Here s a minimalist patch to your code:

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

Note that you cannot write copy (). Generally speaking, parentheses are a little trickier to work with in the do dialect than blocks—they are serving double-duty for precedence! The interpreter thinks copy () means you re trying to parenthesize an expression whose results you want to copy. :(

You can save yourself some headaches by building things up as blocks, and then converting them only at the last minute:

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

P.S. I didn t want to distract from your question by pointing out that the parentheses weren t actually necessary:

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

But the good news about that is that if you re willing to let parens serve a "higher purpose" in this case, there s always compose

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

Composing is like using a "templating dialect", which only reduces the expressions contained in parens, leaving everything else as-is. It s a good way to create code by example, but definitely does run into trouble if your generated code uses parentheses already for precedence! Still...goes to show that your dialects can use parentheses for any purpose, just like they can give meaning to words.

问题回答

暂无回答




相关问题
Rebol Email Pop Server error

I have tested pop successufully with some POP servers with Rebol but it doesn t work with my hosting server dreamhost (which works with Outlook I have tested http://wiki.dreamhost.com/Outlook_Express )...

Rebol and /local Object

The new function below doesn t work if Obj is local. If I remove it from /local it works. So what to do to make it work with a local Obj thanks ? Sure not hard for you. Person: make object! [ Person:...

In Rebol How to get the Object Path Name (String)?

Let s say I have list: [system/history system/prompt] I want to convert to list-string: ["system/history" "system/prompt"] This may be an obvious answer but I can t see any :) Thanks.

What new Widgets in Rebol 3 Vid? [closed]

Rebol 2 VID was hugely missing Dropdownlist and Treeview, I have made a search on Rebol 3 on Google but couldn t find anything except a discussion. So what will Rebol 3 VID really include as new ...

热门标签