2009-10-09 43 views
1

我想创建一个do-libs通用函数来自动加载rebol头文件中列出的一堆库。我想使参数可选,但在后面的情况下,它不工作,为什么?Rebol和unset(可选)参数

Rebol[ 
    libs: [  
    lib1/lib11.r 
    lib1/lib12.r 
    lib2/lib21.r 
    ] 
] 
do-libs 'libs ; works 
do-libs ; doesn't work 

有:

do-libs: func[libs [word! unset!]][ 

    if/else value? 'libs [ 
    foreach lib system/script/header/:libs [ 
     if/else file? lib [ 
     do lib 
     ][  
     do file: to-rebol-file mold lib 
     ]  
    ] 
    ][ 
    ;case with no parameter 
    do-libs 'libs 
    ] 
] 
+0

我已经完全切换到使用R3了。它可以满足我需要的所有功能,而且它的模块系统非常棒。 – 2009-10-10 21:15:01

+0

嗨,谢谢你会尝试一下:从来没有这样做过,直到现在! – 2009-10-11 06:10:24

回答

1

我不是这方面的专家,但我的理解,为了创造一个可以让争论遗漏的,它必须是一个字面的说法,例如,

do-libs: func [ 'libs [word! unset!] ] [ 
    ; blah blah 
]

请注意,libs参数是lit-word!。这也意味着你将有如下调用此函数:

do-libs libs

OR

do-libs

但是,要小心这一点。 REBOL不尊重新的路线。如果你说:

do-libs 
3

它将把3作为参数传递给do-libs和你的函数调用将失败。如果你说

do-libs 
print "ok"

它将把print作为do-libs'libs说法。事实上,REBOL将上述解释为

(do-libs print) "ok"

底线是参数省略是用于REBOL的交互模式。 你不应该用它来做你想做的事。相反,你的函数应该大概是这样的:

do-libs: func [ /name 'word [word!] ] [ 
    if none? name [ word: 'libs ] 
    ; and so on 
]

现在你可以说

do-libs

OR

do-libs/name foo

这是更自然,地道的REBOL。通常,应使用细化来传递可选参数。当参数的数量可能未知或无限时,应使用block!

由于REBOL解释器的工作原理,REBOL很少会支持许多其他语言(C,C++,Ruby等)具有的“参数数组”风格参数。解释器无法知道参数列表的结束位置,除非整个表达式被放在括号中,如下所示:

(foo 1 2 3 "a" "b" "c")
+0

嗨,非常感谢。那么我知道我应该使用改进,这只是我想明白为什么:) 因为这个例子http:// reboltutorial。com/blog/optional-parameter/did工作,我没有使用文字参数。 – 2009-10-11 06:07:42

+0

我通过libs代替lib的原因是我不想被引用像lib1/lib11.r这样的代码库 – 2009-10-11 06:16:56

+1

在R3中,除非引用它,否则你不能进行参数省略,但是在R2中能够。 (我发现这个问题是因为我对即使没有给出url参数时viewtop函数在R2中运行的方式感到困惑)。我不理解允许这一点,使用细化更加一致。 – HostileFork 2010-01-07 21:13:03