[REBOL] nargs
From: maarten::vrijheid::net at: 17-Oct-2003 11:53
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