In Verge there is a function called CallFunction which allows you call a function by a string of its name at runtime.
As of Verge 3.1 there is a newer, more convenient way to perform function calls from just a string. This new syntax is termed as string invocation or string-calling. (For the curious: It is essentially syntax sugar for CallFunction, but it is a change that makes Verge code appear cleaner and more expressive.)
Here is an example.
void MyFunc() { Log("You called me!"); } void AutoExec() { string s = "MyFunc"; s(); // String invocation, which will call the function MyFunc }
This may be done with any string expression.
void MyFunc() { Log("You called me!"); } void AutoExec() { "MyFunc"(); // A literal string. "My" + "Func"(); // A combined expression int dict = DictNew(); DictSetString(dict, "fun", "MyFunc"); DictGetString(dict, "fun")(); // A function call that returns a string. }
String-calls can pass arguments to a function.
void MyNumberFunc(int a) { Log("You called me and passed in a = " + str(a)); } void AutoExec() { "MyNumberFunc"(5); string s = "MyNumberFunc"; s(42); }
A string-call must pass all required arguments of a function, or you will get a runtime error.
void MyNumberFunc(int a) { Log("You called me and passed in a = " + str(a)); } void AutoExec() { "MyFunc"(); // RUNTIME ERROR. Doesn't supply all required arguments! }
However, it is possible to pass more than the required amount of arguments without issues (it'll simply ignore the extra arguments)
void MyNumberFunc(int a) { Log("You called me and passed in a = " + str(a)); } void AutoExec() { "MyNumberFunc"(42, "Whatever"); }But if the function being invoked is a variadic function, it will gather all excess arguments and pass them to the varargs parameter.
void PrintSumOfNumbers(... args) { int i, sum; for(i = 0; args.length; i++) { if(args.is_int[i]) { sum += args.int[i]; } } Log("Sum is " + str(sum)); } void AutoExec() { string func = "PrintSumOfNumbers"; func(3, 4, 5, 10, 200); }
There are limitations though. The string-call statement is treated as void. This means that whatever function is being called will not give a return-value. This in turn, means a string-call cannot appear on the right-hand side of an assignment, or anywhere a string/int expression is expected.
int MyFuncWithReturnValue() { return 42; } void AutoExec() { int a = "MyFuncWithReturnValue"(); // ERROR. Does not compile. string a = str("MyFuncWithReturnValue"()); // ERROR. Does not compile. "MyFuncWithReturnValue"(); // Works. but no return value caught, obviously. }
Despite limitations though, using the string-calling syntax, you can make powerful callback handlers for your scripts, allowing a great degree of abstraction and flexibility.