Hi Maarten,

Not sure if this is better/complete solution version but I just hacked for
fun simmilar function with the same functionality and it also proper counts
the /local words ;-)

example:

>> nargs 'copy
== 1
>> nargs 'copy/deep
== 0
>> nargs 'copy/part
== 1
>> nargs 'copy/local
== 0
>>

--------------------start of code--------------------------

nargs: func [f [word! path!] /local loc? ref? args refs fn rf][
    fn: either word? f [
        get f
    ][
        rf: to-refinement first next to-block f
        get first f
    ]
    args: copy []
    refs: copy []
    parse third :fn [
        any [
            set w word! (
                either ref? [
                    insert tail last refs w
                ][
                    insert tail args w
                ]
            )
            | m: refinement! (
                ref?: true
                insert tail refs reduce [m/1 copy []]
            )
            | skip
        ]
        to end
    ]
    return either rf [
        length? any reduce [select refs rf []]
    ][
        length? args
    ]
]

-------------------end of code--------------------------------


enjoy it,

Cyphre

----- Original Message -----
From: "Maarten Koopmans" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Friday, October 17, 2003 11:53 AM
Subject: [REBOL] nargs


>
> Here is a nargs function that also counts the optional arguments if you
> use refinements (e.g. nargs copy == 1 nargs copy/part == 2).
>
> Enjoy it.
>
> -----------------------------------
>
>   nargs: func
>   [
>     {Returns the total number of args of a function (with and without
>      refinements)}
>     f [word! lit-path!]
>     /local argc f-blk f-ref f-sig ref-pos next-ref-pos
>   ]
>   [
>     ;The total number or arguments
>     argc: 0
>     ;We either have a path or a function
>     ;If we have a path, we count the number
>     ;of arguments of the supplied refinements first.
>     either path? f
>     [
>       ;Translate the path to a block
>       f-blk: to-block f
>
>       ;Is it a function?
>       if not any-function? get/any first f-blk
>       [throw make error! "Rugby error: invocation not on a function"]
>
>       bind f-blk 'do
>       ;The refinements used
>       f-ref: next head f-blk
>       ;the function signature
>       f-sig: first get first f-blk
>       ;Now get the number of arguments foreach refinement
>       ;and add them to argc
>       repeat ref f-ref
>       [
>         ;Find the ref refinement
>         ref-pos: find/tail f-sig to-refinement ref
>         ;If succeed in the find
>         if not none? ref-pos
>         [
>           ;try to find the next one
>           next-ref-pos: find ref-pos refinement!
>           if not none? next-ref-pos
>           [
>             argc: argc + ((index? next-ref-pos) - (index? ref-pos))
>           ];if not none next-ref-pos
>         ];if not none? ref-pos
>       ];foreach ref f-ref
>
>     ];either path? f first clause
>     [
>       if not any-function? get/any f
>       [ throw make error! "Rugby error: invocation not on a function" ]
>       f-sig: first get f
>     ];either path? f second clause
>
>     ;Add the number of function arguments
>     argc: argc + -1 + index? any [ find f-sig refinement! tail f-sig ]
>
>   ];nargs
>
>
> --
> To unsubscribe from this list, just send an email to
> [EMAIL PROTECTED] with unsubscribe as the subject.
>
>

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.

Reply via email to