tags:

views:

48

answers:

1

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
  ]
]
+1  A: 

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")
Gregory Higley
Hi thanks a lot. Well I know I should use refinements, it's just I want to understand why :)Because this example http://reboltutorial.com/blog/optional-parameter/ did work and I didn't use a literal argument.
Rebol Tutorial
The reason I pass 'libs instead of lib is I don't want to be obliged to quote the lib like "lib1/lib11.r"
Rebol Tutorial
In R3 you can't do the argument omission unless it's quoted, but in R2 you can. (I found this question because I was puzzling over how the viewtop function was running in R2 even when no url parameter was given.) I don't understand the point of allowing that, using refinements is more consistent.
Hostile Fork