Why is it not possible to access static fields of a class via Type.getClass()? - class

In Haxe, it is possible to get the class of an object with the following function:
Type.getClass(myObject);
If the object myObject is an instance of the class myClass, which contains a static field, I should be able to access this static field:
class MyClass
{
public static myStaticField:Int = 5;
}
public var myObject = new MyClass();
//expected trace: "5"
trace (Type.getClass(myObject).myStaticfield);
But the result is:
"Class <MyClass> has no field myStaticField."
Any idea why?

You need to use reflection to get such value:
class Test {
#:keep public static var value = 5;
static function main() {
var test = new Test();
var v = Reflect.field(Type.getClass(test), "value");
trace(v);
}
public function new() {}
}
Note that to prevent DCE (dead code elimination) I had to mark the static var with #:keep. Normally DCE is going to suppress that variable because it is never referred directly.
Working example here: http://try.haxe.org/#C1612

Try the Reflect class (Specifically the callMethod or getProperty functions).

Related

Dart: Referring to Singleton class from within itself

I have a singleton class and I would like to refer to it from within itself, however I am getting a CyclicInitializationError (Reading static variable 'instance' during its initialization) when trying to do so.
Here is an example:
void main(){
Singleton newSingleton = Singleton();
print(newSingleton.member);
}
class Singleton {
static final instance = Singleton._internal();
Singleton._internal();
factory Singleton(){
return instance;
}
String member = "hello";
String hamburger = instance.member; // This line causes the error to be thrown
}

Actionscript Classes: variable reference within method not recognized

Whenever I try to access a variable within a class method, Flash gives the error message: Access of undefined variable
This is true for variables vertices, i, deltap, etc. below. All of these should be defined for the whole class, as far as I can see. What am I missing?
package
{
import flash.display.Shape;
import flash.display.Graphics;
import fl.motion.Color;
public dynamic class Quadrilateral extends Shape {
public var vertices:Array = new Array();
public var endvertices:Array;
public var angle:Number;
public var mycolor:Color;
private var steps:Number;
private var deltap:Array = new Array(4);
private var i:Number;
public function Quadrilateral(vertexlist, fillcolor, stepcount=100) {
vertices = vertexlist;
mycolor = fillcolor;
steps = stepcount;
drawme()
}
public static function setfinal(vertexlist) {
endvertices = vertexlist;
for (i=0;i<4;i++) {
deltap[i] = (endvertices[i] - vertices[i])/100;
}
}
}
You are missing that the method is static, which means that you cannot access non static members from inside it.
That method should not be static.

How to use addChild() w/o extension from another class?

Is it possible to use addChild() without 'extends' from another Class ?
It's strange, that i need to extension from another classes to use it ... but maybe its my lack of knowledge in as3 ...
Main:
public class Main extends Sprite
{
private var sprite:Sprite = new Sprite();
public function Main()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var myVar:MyClass = new Myclass();
addChild(myVar);
}
}
MyClass:
public class MyClass
{
private var sprite:Sprite = new Sprite();
public function MyClass()
{
sprite.graphics.lineStyle(1, 0x990000, 1);
sprite.graphics.drawRoundRect(5, 5, 500, 150, 10, 10);
addChild(sprite);
}
}
addChild is method that add's DisplayObject to DisplayObjectContainer, so yes, you must extend your custom classes if you want to see it on screen
futher reading: http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3e.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html
I looks like you're trying to do this:
public class MyClass
{
private var sprite:Sprite;
public function MyClass(container:MovieClip)
// ^^^^^^^^^ Take a reference to a container to add children to.
{
sprite = new Sprite()
sprite.graphics.lineStyle(1, 0x990000, 1);
sprite.graphics.drawRoundRect(5, 5, 500, 150, 10, 10);
container.addChild(sprite);
// ^^^^^^ Add internal sprite to the referenced container.
}
}
Where you provide a container to add children to.
Meaning your Main class will simply pass a reference to itself to your MyClass instance.
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var myVar:MyClass = new MyClass(this);
// ^^^^ Simply pass the main class as the container.
}
Another option is to simply expose sprite from MyClass and then use:
addChild(myVar.sprite);
In your Main class.
The simple answer to your question is: no, a custom class cannot addChild without extending a subclass of DisplayObjectContainer. The method addChild() and its related methods are defined in DisplayObjectContainer and only subclasses of it can use them.
You often see the method addChild() used without a calling object (ex: theobject.addChild()) but that's only because the keyword "this" is implied. In reality addChild() is always called by a DisplayObjectContainer instance.

is it possible to put Class in a variable and access the class's static variables and functions in actionscript3?

Say I had the following class
public class Scene{
public static var title="new scene";
public function Scene(){}
public static function start() { trace("scene started"); }
}
How can you access the Scene class's static variables and functions like this?
var i:Class = Scene;
trace(i.title);
i.start();
I'm trying to figure out how variables assigned with Class work in actionscript.
Any tips would be welcome. Thanks.
Static methods are called from the class:
trace(Scene.title);
Scene.start();
Singleton patterns enable constructor, local reference, and potentially abstraction through interface classes.
Example of Scene as a singleton:
package
{
public class Scene
{
private static var instance:Scene = new Scene();
public static function getInstance():Scene
{
return instance;
}
public var title:String = "new scene";
public function Scene()
{
if (instance)
throw new Error("Scene is a singleton and can only be accessed through Scene.getInstance()");
}
public function start():void
{
trace("scene started.");
}
}
}
Your example implementation would now be:
var i:Scene = Scene.getInstance();
trace(i.title);
i.start();
This is how you can access the dynamic class (Scene) & it's properties / methods :
var myDynamicClasses:Array = [Scene]; // Required
var i:Class = Class(getDefinitionByName("Scene"));
trace(i.title);
i.start.call();
This could throw an error, if the first line is not included. Because, when the compiler notices the class Scene (not the one from adobe's package) is not being used it ignores it. Thus it would be not available for dynamic initialization.
We could force the compiler to include these classes by putting these class names in variables or declare an array as above as a quick hack.
If you have many dynamic classes, you could add a reference to them in this array & each class will be included by the compiler for dynamic initialization.
var i:Class = Scene;
trace(i.title);
Should throw an error because the compiler can no longer assume that i is a scene when it gets to line 2. If you were to coerce the Class object, it should work.
var i:Class = Scene;
trace((Scene(Class).title);

Creating an object passing a lambda expression to the constructor

I have an object with a number of properties.
I want to be able to assign some of these properties when I call the constructor.
The obvious solution is to either have a constructor that takes a parameter for each of the properties, but that's nasty when there are lots. Another solution would be to create overloads that each take a subset of property values, but I could end up with dozens of overloads.
So I thought, wouldn't it be nice if I could say..
MyObject x = new MyObject(o => o.Property1 = "ABC", o.PropertyN = xx, ...);
The problem is, I'm too dim to work out how to do it.
Do you know?
C# 3 allows you to do this with its object initializer syntax.
Here is an example:
using System;
class Program
{
static void Main()
{
Foo foo = new Foo { Bar = "bar" };
}
}
class Foo
{
public String Bar { get; set; }
}
The way this works is that the compiler creates an instance of the class with compiler-generated name (like <>g__initLocal0). Then the compiler takes each property that you initialize and sets the value of the property.
Basically the compiler translates the Main method above to something like this:
static void Main()
{
// Create an instance of "Foo".
Foo <>g__initLocal0 = new Foo();
// Set the property.
<>g__initLocal0.Bar = "bar";
// Now create my "Foo" instance and set it
// equal to the compiler's instance which
// has the property set.
Foo foo = <>g__initLocal0;
}
The object initializer syntax is the easiest to use and requires no extra code for the constructor.
However, if you need to do something more complex, like call methods, you could have a constructor that takes an Action param to perform the population of the object.
public class MyClass
{
public MyClass(Action<MyClass> populator)
{
populator.Invoke(this);
}
public int MyInt { get; set; }
public void DoSomething()
{
Console.WriteLine(this.MyInt);
}
}
Now you can use it like so.
var x = new MyClass(mc => { mc.MyInt = 1; mc.DoSomething(); });
Basically what Andrew was trying to say is if you have a class (MyObject for eg) with N properties, using the Object Initializer syntax of C# 3.0, you can set any subset of the N properties as so:
MyObject x = new MyObject {Property1 = 5, Property4 = "test", PropertyN = 6.7};
You can set any of the properties / fields that way./
class MyObject
{
public MyObject(params Action<MyObject>[]inputs)
{
foreach(Action<MyObject> input in inputs)
{
input(this);
}
}
}
I may have the function generic style wrong, but I think this is sort of what you're describing.