Argy
Zero-dependency Swiss Army knife for variadic functions.
What is it?
Tired of handling variadic function babysitting like this:
/*** Query stuff* @param* @param* @param*/this { if _ && _ && _isFunction // Called as query(id, query, callback) // Argument are correct else if _ && _ // Called as query(id, callback) id query callback = undefined id query; // Destructuring for the win! else if _ // Called as query(callback) id query callback = undefined undefined id; else // ... and yet more conditions // Now we can get on with stuff};
... of course its even worse when you don't have destructuring available.
Argy removes the need to do function argument mangling and allows you to specify what a function can accept in a simple syntax.
Some examples
// Make a query function that can accept three parameters: a string, an object and a callback (required)thisquery = ; // Alternate syntax of the abovethisquery = argy
// Create a function that acts differently depending on how it was called (overloading)this {
Basic usage
Argy operates by selecting two paths - how you specify the function standard and what you do with it afterwards:
-
The specification specifier - choose either the as or builder specification setups. If you want different specifications to do different things use ifForm.
- as syntax - Use a string to specify what a function can accept (e.g.
argy().as('string [number]')
) - single function syntax - An alternative way to specify
as
syntax is to pass two parameters to argy (e.g.argy('[string] [number]', function(name, number) { ... })
) - builder syntax - Use an object based declaration to specify the function standard (e.g.
argy().required('string').optional('number')
) - ifForm syntax - Specify different callbacks to run for different forms (e.g.
argy().ifForm('string', funcFoo).ifForm('number', funcBar')
)
- as syntax - Use a string to specify what a function can accept (e.g.
-
The output handler - choose either the wrap or parse APIs
- wrap - Return a function that will be called by Argy when the specification is satisfied (e.g.
argy().as('... your spec ...').wrap(function(a, b, c) { // Your function // })
) - parse - Return an array of extracted parameters (e.g.
argy().as('... your spec ...').parse()
). This method is useful if you have destructuring available in your parser.
- wrap - Return a function that will be called by Argy when the specification is satisfied (e.g.
Casting
Argy also supports variable casting. This forces an incomming value to be of a certain type. Since some types are not translatable the functionality to convert between types is limited but this can be helpful when requiring an input to be of a certain style. Casting is specified in the as syntax using the greater-than operator after the type e.g. scalar>string
will force any scalar input into the string type.
For more details see the Argy.cast() function.
; ; ;
Specification API
ifForm()
Run a callback if the form of the arguments matches a rule.
ifForm(String <match> | Array <matches>, callback)
ifFormElse(callback)
Rules can be single strings or arrays. If an array is passed any rule within that array is counted as satisfying the form (an 'OR' rule).
Strings can be composed of parameters seperated by spaces or commas with optional pipes (|
) to specify multiple types: e.g. string string|number date
indicates that the first argument should be a string, the second could be a string OR a number and the third should be a date.
// The following function tries to identify a person and their age based on optional arguments { var id; return id;}; // "Matt (30)" // "Joe" // "Unknown (23)" // "Unknown"
See the test/ifForm.js for more complex examples.
as()
The as()
method is a shorthand version of the add()
/ required()
/ optional()
methods.
'As' syntax resembles a string (either space separated or CSV) of types with optional types in square brackets:
// Require a single number // Require any type // Require a string followed by an optional number // Require a number preceeded by an optional string (reverse of above with args expanding from right)
See the test/as.js for more complex examples.
builder
The builder format uses object chains to lay out a specification.
// Wrap a function with an optional string, required number and optional date
See the test/wrap.js for more complex examples.
Output API
parse()
Compile a specification against incoming arguments and return an array of the correct response.
Parse is especially useful if your language has destructuring support.
// Parse values of a function { var name callback = ;}
See the test/parse.js for more complex examples.
wrap()
Factory function which returns a wrapped function where the function arguments will be rearranged into the correct order.
This function provides a convenient way to specify the different specifications of arguments (using the .as()
, .add()
/ .required()
/ .optional
methods), then rewriting the args so the arguments are dependable.
// Apply a wrapper to a new functionvar myFunc = argy;
It is also possible to pass two parameters to Argy to replicate the same functionality:
// Apply a wrapper to a new functionvar myFunc = ;
See the test/wrap.js for more complex examples.
Utility APIs
argy().getSpecString()
Return the compiled version of a specification as a space seperated string.
This is the opposite function to as()
.
// Get the specification syntax from an Argy instance compiled with 'as()' // => 'string [date] callback' // Get the specification syntax from an Argy instance compiled using the builder syntax // => 'string [date] callback');
Argy.as()
Shortcut function to create a new Argy instance without specifying any parameters.
This is functionally identical to argy().as()
Argy.cast()
Attempt to convert an input type into an output type. Since some types are not translatable the functionality to convert between types is limited.
argy '123'argy 0argy 456argy 'foo'argy 123
See the test/cast.js for more complex examples.
Argy.getForm(arguments)
Returns a space separated string of the arguments object where each item is run via getType
.
{ argy // => "string number date"};;
Argy.getType(variable)
Returns the lower-case type specification of a variable.
argy // => 'string'argy // => 'array'argy // => 'object'argy // => 'date'argy // => 'function'
Argy.isType(variable, types)
Compares a single variable against a type or array of types.
If types
is an array this function will return true if any of the array items match.
In addition to the types returned by getType()
this function also supports the following meta-comparators:
Type | Description |
---|---|
* / any |
Always returns true |
scalar / basic |
Match any number, string or boolean |
ok / truey |
Match any non-null or non-undefined type |
notok / falsy |
Match any null or undefined type |
callback / cb |
Aliases of 'function' |