Variadic Functions

Introduced in Verge 3.1, VC has variadic functions, also called variable-argument functions or 'varargs' function. Basically what this allows you to do is create a function that can accept any number of arguments, and handle these arguments as an indexable array. It's an advanced feature, but can be used to do all sorts of clever things.

So an example of how to declare a variable-argument function, is done like so:

void MyFunc(... args)
{
}

"..." is a special variable type identifier, which denotes that the parameter being declared will accept any number of arguments.

Since ... just refers to the variable type it is possible to rename the variable to something other than "args" else if you'd prefer another name:

void MyFunc(... arguments)
{

}

To call a varargs function, you simply pass a comma separated list of all the arguments you're supplying the function. Note that varargs parameters can accept strings, ints, or absolutely nothing. All of the following are valid calls on the above MyFunc() function

MyFunc();
MyFunc(1, "hello");
MyFunc(1, 3, 4, 4424, 3);
MyFunc("bob");

If we only have a varargs parameter in our function, we could still get away with passing no arguments, or perhaps less than our function logic would want to expect.

But, you can be relieved, since it is still possible to have required arguments that must be passed before the optional varargs list. The only syntactic requirement is that you always declare required arguments before a varargs argument (that is to say the varargs parameter can only be the final parameter declared, and there can only be one varargs variable per function, for obvious reasons)

void MyFunc(string name, int count, ... args)
{

}
To actually use the varargs parameters, you refer to variable (like "args") by name and then access its members like a struct, by writing a "." (dot) between the variable name and the members. Variable argument lists have the following members (change "args" for whatever the name of your parameter is):
int args.length;			(read-only) // The number of varargs arguments
int args.int[argument];			(read/write) // For integer valued arguments
string args.string[argument];		(read/write) // For string valued arguments
int args.is_int[argument];		(read-only) // For checking if an argument is an integer type
int args.is_string[argument];		(read-only) // For checking if an argument is a string type
In the case an argument is not of the type you're checking, it'll return "" for strings or 0 for ints, which is a lot nicer than blowing up in your face. Here is a simple example that adds a bunch of numbers together:
int AddNumbers(... args)
{
	int i, sum;
	for(i = 0; args.length; i++)
	{
		if(args.is_int[i])
		{
			sum += args.int[i];
		}
	}
	return sum;
}
Another thing to note is that the varargs parameter may be passed down to further functions, so you could write something like this AFTER the above example:
int FourPlusNumbers(... args)
{
	return AddNumbers(4, args); // Will pass 4, followed by all arguments passed to this call.
}
Potentially nifty function chaining things can be done as a result of this. I'll leave the creativity up to you.
Talkback

Post a new comment?

Talkback #2 written by Overkill on 2008-12-28.

Here's a fairly simple (but possibly handy) varargs function for logging text.

// Print
// Logs a message from a list of mixed string/int arguments and prints it with tabs
// Pass: args - The arguments to print
void Print(... args)
{
	string s;
	int i;
	for(i = 0; i < args.length; i++)
	{
		if(args.is_int[i])
		{
			if(i) s += "	";
			s += str(args.int[i]);
		}
		if(args.is_string[i])
		{
			if(i) s += "	";
			s += args.string[i];
		}
	}
	Log(s);
}
Example usage:
Print("Hey look it's like Log() except for ", 1, " thing, it takes varargs");

Talkback #1 written by Overkill on 2008-12-27.

I present DictConstruct, which can create and populate a dictionary in the same call.

// DictConstruct
// Constructs a dictionary and populates it using the string arguments given to it.
// Pass: args - strings of the form "key:value"
// Returns: A dictionary handle populated with the key-to-value mappings you supply.
int DictConstruct(... args)
{
int i;
int dict = DictNew();
string k, v;
for(i = 0; i < args.length; i++)
{
if(args.is_string[i])
{
k = GetToken(args.string[i], ":", 0);
v = TokenRight(args.string[i], ":", 1);
DictSetString(dict, k, v);
}
else
{
Exit("DictConstruct: Argument " + str(i) + " must be a string value.");
}
}
return dict;
}
Here is an example usage:
int dict = DictConstruct("name:Bob", "job:Fighter", "attack:54");

Post a new comment?

Doc Nav

Your docs
View All Docs

If you log in, you can edit the documentation, or create your own documents and tutorials!

Ben McGraw's lovingly crafted this website from scratch for years.
It's a lot prettier this go around because of Jon Wofford.
Verge-rpg.com is a member of the lunarnet irc network, and would like to take this opportunity to remind you that regardless how babies taste, it is wrong to eat them.