Rebol и unset (необязательный) параметр - PullRequest
1 голос
/ 09 октября 2009

Я хочу создать универсальную функцию do-libs для автоматической загрузки группы 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
  ]
]

1 Ответ

1 голос
/ 11 октября 2009

Я не эксперт в этом, но мое понимание заключается в том, что для создания функции, которая допускает пропуск аргумента, он должен быть буквальным аргументом, например,

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 аргументом 'libs do-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")
...