call constructors by using bracket syntax in AS3 - actionscript-3

As you know,you can access properties and methods in two ways:
dot syntax: object.property=value;
&
bracket syntax: object["property"]=value; or object["property"]=["value];
The bracket syntax also works for methods:
this["myMC"]["stop"]();
I tried to do that with constructors and i "Failed" :(
I try to make variables but
This code does NOT work:
this["mySprite"]=new ["Sprite"](); Error:Instantiation attempted on a non-constructor.
or
this["mySprite"]=new ["Sprite()"]; Error:Instantiation attempted on a non-constructor.
or
this["mySprite"]=["new Sprite"](); Error:Value is not a function.
or
this["mySprite"]=["new Sprite()"]; Error:a term is undefined and has no properties
None of them work
Maybe you wonder why i want that:
I want to make new variables at runtime:
this[tf1.text]=new [tf2.text]();
tf1.text is my variable's name and tf2.text is my constructor.
then I set properties and methods of my variable at runtime(you know how).
I appreciate helpful answers.

You can use getDefinitionByName() to get the class from a string, then create a new object from that class.
This is an example for getting the Sprite class from a string.
import flash.utils.getDefinitionByName;
var aClass:Class = getDefinitionByName("flash.display.Sprite") as Class;
var sprite:Sprite = new aClass();

Related

When using the 'Class' datatype, how can I specify the type so I only accept subclass of a specific class?

I've got a method that accepts a parameter of type Class, and I want to only accept classes that extend SuperClass. Right now, all I can figure out to do is this, which does a run-time check on an instance:
public function careless(SomeClass:Class):void {
var instance:SomeClass = new SomeClass();
if (instance as SuperClass) {
// great, i guess
} else {
// damn, wish i'd have known this at compile time
}
}
Is there any way to do something like this, so I can be assured that a Class instance extends some super class?
public function careful(SomeClass:[Class extends SuperClass]):void {
var instance:SuperClass = new SomeClass();
// all is good
}
If you are going to instantiate it anyway, why not accept an object instead which allows you to type it to :SuperClass?
careless(SomeClass);
//vs.
careless(new SomeClass);
Not too much of a problem there as far as your code goes.
There are a few differences though:
The object has to be created, because an object is required. If your function does not instantiate the class under some circumstances, this can be a problem. Additional logic to pass either an object or null can bloat the function call.
If you cannot call the constructor outside that function, it won't
work either.
All that is solved by the factory pattern. Pass a factory as the parameter that produces SuperClass objects.
function careful(factory:SuperClassFactory)
Your requirements:
I want to only accept classes that extend SuperClass
and
I need to pass in a Class so that it can be instantiated many times
by other objects later
Can be met by passing in an instance of the class you need, and using the Object.constructor() method.
public function careful(someInstance:SuperClass):void {
//you probably want to store classRef in a member variable
var classRef: Class = someInstance.constructor();
//the following is guaranteed to cast correctly,
//since someInstance will always be a descendant of SuperClass
var myInst:SuperClass = new classRef() as SuperClass;
}
More reading here.
You can't do that in ActionScript 3. In languages like C# you can do something like (forgive me if the syntax is off):
public void Careless<T>() where T : SuperClass
But AS3 does not have 'generics'. Unfortunately the only way I know how to do what you want is the way you have already done.
A pattern that might be more suitable for your use case might be something like:
class SuperClass
{
public static function careless():void
{
var instance:SuperClass = new SuperClass();
// ...
}
}
The only way to have static type checking in ActionScript 3 is to provide an instance of a class.
It is possible but it's expensive. You can use on a Class (not instance) the:
flash.utils.describeType
You then get an XML with a bunch of information including inheritance for that class. Like I said it's an expensive process and probably creating an instance and checking it will be in most cases faster.

Dynamic Class Initiation AS3

I´m trying to initialize a class, based on a concatenation of a string and a number.
All my classes are public.
This is my code:
public function setCurrentPath(pathNumber:String)
{
var pth_class:Class = getDefinitionByName('Pth'+pathNumber) as Class;
var pth:MovieClip = new pth_class();
addChild(pth)
pth.getXY();
}
So I´m getting Error #1065.
Any help?
Yes I have up on my class file import flash.utils.*
Is your pth_class variable null?
If so, there are a couple of reasons this might be the case:
1) You haven't input the correct fully qualified class name of your class. E.g com.myClasses.Pth1
or
2)
If you're instanciating classes dynamically like this and there is no other "regular" reference to the class (such as blah = new Pth1()) then the "Pth1" class won't be included in the compilation process.
To get around this I think you can supply arguments to the compiler to force it to compile those classes OR you can manually include references to them in your existing code:
p1:Pth1;
p2:Pth2;

Can I create an instance of a class from AS3 just knowing his name?

Can I create an instance of a class from AS3 just knowing it's name? I mean string representation, like FlagFrance
Create instances of classes dynamically by name. To do this following code can be used:
//cc() is called upon creationComplete
private var forCompiler:FlagFrance; //REQUIRED! (but otherwise not used)
private function cc():void
{
var obj:Object = createInstance("flash.display.Sprite");
}
public function createInstance(className:String):Object
{
var myClass:Class = getDefinitionByName(className) as Class;
var instance:Object = new myClass();
return instance;
}
The docs for getDefinitionByName say:
"Returns a reference to the class object of the class specified by the name parameter."
The above code we needed to specify the return value as a Class? This is because getDefinitionByName can also return a Function (e.g. flash.utils.getTimer - a package level function that isn't in any class). As the return type can be either a Function or a Class the Flex team specified the return type to be Object and you are expected to perform a cast as necessary.
The above code closely mimics the example given in the docs, but in one way it is a bad example because everything will work fine for flash.display.Sprite, but try to do the same thing with a custom class and you will probably end up with the following error:
ReferenceError: Error #1065: Variable [name of your class] is not defined.
The reason for the error is that you must have a reference to your class in your code - e.g. you need to create a variable and specify it's type like so:
private var forCompiler:SomeClass;
Without doing this your class will not be compiled in to the .swf at compile time. The compiler only includes classes which are actually used (and not just imported). It does so in order to optimise the size of the .swf. So the need to declare a variable should not really be considered an oversight or bug, although it does feel hackish to declare a variable that you don't directly use.
Yes, use getDefinitionByName:
import flash.utils.getDefinitionByName;
var FlagFranceClass:Class = getDefinitionByName("FlagFrance");
var o:* = new FlagFranceClass();

Instantiate a class from a string in ActionScript 3

I've got a string which, in run-time, contains the name of a class that I want to instantiate. How would I do that?
I read suggestions to use flash.utils.getDefinitionByName():
var myClass:Class = getDefinitionByName("package.className") as Class;
var myInstance:* = new myClass();
However, that gives me the following error:
[Fault] exception, information=ReferenceError: Error #1065: Variable className is not defined.
The easiest method I've come up with is to simply write the classnames out, separated by semicolons, anywhere in your project.
e.g. I create an Assets.as file with this in it:
package {
public class Assets {
// To avoid errors from the compiler when calling getDefinitionByName
// just list all of the classes that are not otherwise referenced in code:
Balloon;
Cloud;
FlyingHorse;
FlyingPig;
UFO;
Zeppelin;
}
}
Full code example/tutorial on this is here: http://producerism.com/blog/flashpunk-dame-and-lua-tutorial-part-6/
The other option is to use the mxmlc -includes compiler argument like this:
-includes=com.mydomain.package.MyClass
http://blogs.adobe.com/cantrell/archives/2010/09/loading-classes-dynamically-in-actionscript-3.html

AS3 Access the methods of a dynamically created movieclip

How do I access the methods of a dynamically created movieclip/object?
For simplicity sake I didn't post code on how I dynamically created the movieclip. Instead, assume its already created. It is an object. It is called field_2. Below it is referenced by using getChildByName('field_' + field.id);
Check_box_component.as
public var testVar:String = 'test';
public function testReturn()
{
return 'value returned';
}
Main.as
var temp:MovieClip = MovieClip(getChildByName('field_' + field.id));
trace(temp);
trace(temp.testReturn);
trace(temp.testVar);
Output:
[object Check_box_component]
function Function() {}
test
When I trace temp.testReturn, why does it show "function Function() {}" instead of "value returned"?
This link below helped me get this to this point.
http://curtismorley.com/2007/06/13/flash-cs3-flex-2-as3-error-1119/
have you tried:
trace(temp.testReturn());
... instead of your
trace(temp.testReturn);
... ?
I think you will have the result you are waiting for.
Actually, when doing "temp.testReturn", you are not calling the function. You need to add the parenthesis to make the actual call.
When you make a trace of temp.testReturn, the function is not executed: the trace function tell you the type of temp.testReturn, which is here correctly returned as a "function" type.
There is a difference between a function reference and a function call. Parenthesis '()' are an operator sign of ActionScript. They tell the compiler "please try to make a call to what was just behind us". Or at least I hope they are that polite.
A function in ActionScript is an object, like all other stuff. A member of Function class. You can pass it's reference back and forth, you can even call it's methods like call() or apply().
If you want a call, and not a reference, you have to use call operator.
trace(temp.testReturn());
EDIT You accepted an answer while I was typing, sorry for a duplicate answer.