I've got a function wich can accept a varible number of parameter with a rest operator.
I want create an object passing the argument collected with the rest operator directly to a constructor without create an object and call an initializing function and without passing the entire array but the parameters ah I do with apply() function.
Is it possible ? Using apply doesn't work.
public function myFunc(...arg) {
// something link "new MyClass.apply(args)"
return new MyClass();
}
In this example, we have created the constructor of Student class that have two parameters. We can have any number of parameters in the constructor.
In the Java edition of Building Maintainable Software, Joost Visser advises keeping the number of parameters to no more than four. The same guideline probably applies to almost all other programming languages, like C#, Scala and even FORTRAN and COBOL. The issue is perhaps moot in languages like Malbolge.
To use a variable number of arguments to function, use the arguments object.
Note the difference between parameters and arguments: Function parameters are the names listed in the function's definition. Function arguments are the real values passed to the function. Parameters are initialized to the values of the arguments supplied.
Unfortunately no. There is no way to make apply work for constructor. What is done generally is to prepare a number of call based on the number of arguments :
public function myFunc(...arg):Myclass {
switch (arg.length) {
case 0:return new MyClass();
case 1:return new MyClass(arg[0]);
case 2:return new MyClass(arg[0], arg[1]);
//... etc
case n:return new MyClass(arg[0], arg[1],..,arg[n]);
default: throw new Error("too much arguments in myFunc");
}
}
Well this led me to an interesting long research!
I found this neat SWC file filled with utils for mimicking the AS2 eval(): http://www.riaone.com/products/deval/index.html
And here's a proof of concept that what you're looking for might actually work:
package tests {
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.utils.getQualifiedClassName;
import r1.deval.D;
public class RandomTests extends Sprite{
public function RandomTests() {
super();
var test:BitmapData = create(BitmapData, 100, 100, true, 0x00000000);
trace(test);
}
public function create( pClass:Class, ... pArgs ):* {
D.importClass(pClass);
var fullQName:String = getQualifiedClassName(pClass);
var qNameSplit:Array = fullQName.split("::");
var className:String = qNameSplit[1];
fullQName = qNameSplit.join(".");
var statements:String =
"import $0;\n" +
"return new $1($2);";
var args:Array = [];
for (var a:int = 0, aLen:int = pArgs.length; a < aLen; a++) {
switch(pArgs[a].constructor) {
case String:
args[a] = "\"" + pArgs[a] + "\"";
break;
default:
args[a] = pArgs[a];
break;
//throw new Error("Unhandled type, please add it: " + pArgs[a].constructor);
}
}
return D.eval(XString.gsub(statements,[fullQName, className, args.join(",")]));
}
}
}
Sorry for the bits of dependencies (Like my XString class for easy sub-replacements) but it does work in theory. The only issue would be passing object references as argument entries. But then again... the r1.deval.D class might be able to take it... hmm.
Anyways, thought maybe this would be worth sharing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With