重新设置和取消设置(可选)参数

发布于 2024-08-07 04:16:54 字数 540 浏览 2 评论 0原文

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

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
  ]
]

I want to create a do-libs generic function to automatically load a bunch of libs listed in rebol header files. I want to make the parameter optional but in that later case it doesn't work why ?

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

with:

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
  ]
]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

就是爱搞怪 2024-08-14 04:16:54

我不是这方面的专家,但我的理解是,为了创建一个允许省略参数的函数,它必须是一个文字参数,例如,

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

请注意,libs 参数是一个 <代码>lit-word!。这也意味着您必须按如下方式调用此函数:

do-libs libs

或者

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 等)所具有的“param array”样式参数。解释器无法知道参数列表在哪里结束,除非整个表达式放在括号中,如下所示:

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

I'm not an expert in this, but my understanding is that in order to create a function that allows argument omission, it has to be a literal argument, e.g.,

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

Note that the libs argument is a lit-word!. This also means you would have to call this function as follows:

do-libs libs

OR

do-libs

However, be careful with this. REBOL does not respect new lines. If you say:

do-libs
3

It will regard 3 as an argument to do-libs and your function call will fail. If you say

do-libs
print "ok"

It will regard print as the 'libs argument of do-libs. In fact, REBOL interprets the above as

(do-libs print) "ok"

The bottom line is that argument omission is intended for REBOL's interactive mode. You shouldn't use it to do what you're trying to do. Instead, your function should probably look like this:

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

Now you can say

do-libs

OR

do-libs/name foo

This is more natural, idiomatic REBOL. In general, refinements should be used to pass optional arguments. When the number of arguments is potentially unknown or unlimited, a block! should be used.

Because of how the REBOL interpreter works, it's very unlikely that REBOL will ever support the "param array" style arguments that many other languages (C, C++, Ruby, etc.) have. The interpreter would have no way of knowing where the argument list ends, unless the entire expression was placed in parentheses like so:

(foo 1 2 3 "a" "b" "c")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文