AS3: Static scope question - actionscript-3

I've always found this interesting, and haven't managed to fully understand it yet. Take this class:
package
{
public class SomeClass
{
private var _myvar:String = "hello";
public static function sayHello():void
{
trace(_myvar);
}
}
}
As we know, this will throw an error unless I declare _myvar as private static var _myvar
1120: Access of undefined property _myvar.
I don't completely understand why _myvar isn't in scope unless it's static. Can anyone provide a easy to understand explanation of this?

As _myvar is not static it's a property that is attached to an instance of SomeClass, i.e. it has only meaning each time you create a new SomeClass.
In contrary a static property is attached to the Class object, it exists only once and is not dependent of each instance of SomeClass created.
So when you try to reach _myvar from your static function sayHello it's the same as calling this._myvar but you have only one static property and can have multiple instance created over the timelife of your application, what should be the value of this in that case ?

Related

why cant I access a public method?

When I'm using from Main.as:
appleObject.setX(50);
to call the function which is in Floater.as:
public function setX(positionX):void {
trace("hello");
}
from Floater.as, but I get the error 1120: Access of undefined property appleObject.
Main.as: http://pastebin.com/CHMdYM8r
Floater.as: http://pastebin.com/BV4PbfXe
To elaborate on what has been said in the comments:
In AS3 class files, all functional code needs to be wrapped in a method (function).
So when the compiler sees this line:
appleObject.setX(50);
It is expecting it to be either a variable declaration, or a function declaration. Move that line inside a function, and the compiler error should go away. As suggested by #DodgerThud in a comment, putting it in the constructor would make a lot of sense:
public function Main():void {
score.text = "hello";
addChild(bananaObject);
addChild(appleObject);
appleObject.setX(50);
//...rest of code
As an aside, it's also a good practice to not instantiate complex objects in the class scope. So this would be even better:
private var appleObject:Floater;
public function Main():void {
score.text = "hello";
addChild(bananaObject);
appleObject = new Floater();
addChild(appleObject);
appleObject.setX(50)

AS3 Access stage object in singleton returns null

I know singletons are sensitive subjects, but I really don't want to hear anything about that, or what you think about this implementation. This question is not about that.
So, I have implemented a singleton using a static var with the instance.
private static var instance:SomeClass = new SomeClass();
public static function getInstance():SomeClass {
return instance;
}
SomeClass is a class in the library, and inside that one there some instance called someSymbol.
For some reason, when I use SomeClass as a singleton, every time I want to access someSymbol I get Cannot access a property or method of a null object reference. But if I implement SomeClass with regular instantiation the error disappears.
I've tried accessing someSymbol in different ways but I always get the error.
someSymbol.rotation = 0;
and also
var aSymbol = getChildByName("someSymbol");
aSymbol.rotation = 0;
and also
trace(someSymbol); // null
trace(this['someSymbol']); // null
trace(SomeClass.instance.someSymbol); // throws error
So why do I get null when using this singleton implementation, and not when instantiating the class as usual?
Edit:
Thanks to #Marty Wallace answer, I changed my singleton implementation and now it works.
So, instead of instantiating the instance this way:
private static var instance:SomeClass = new SomeClass();
I instead instantiate it the first time getInstance() is called, as #Marty does it.
I don't know exactly what is going on behind the curtains, but it seems as if SomeClass wasn't fully exported when instantiating before the document class is running.
Your example is working fine for me:
public class Singleton
{
private static var _instance:TestClip;
public static function get instance():TestClip
{
if(_instance === null) _instance = new TestClip();
return _instance;
}
}
And TestClip has an inner MovieClip with the instance name inner:
trace(Singleton.instance.inner); // [object MovieClip]
Do you have any luck if you make a class for SomeClass and make a getter for someSymbol like this?
public function get someSymbol():MovieClip
{
return this["someSymbol"];
}

Bindable(event="...") public static function

I am trying to bind to a static function, I designate a binding event name and then fire the event from another static function.
[Bindable(event="dataUpdated")]
public static function string(path:String) :String
{
...
}
private static function updateData() :void
{
//doSomthing;
staticEventDispatcher.dispatchEvent(new Event('dataUpdated'));
}
private static var staticEventDispatcher:EventDispatcher = new EventDispatcher();
My view is not updating when the event is fired, is there a better way to do this?
I have also tried dispatching the event from an instance of the class, I added this staticEventDispatcher as a last resort, but it didn't work.
The point in this if for language translations within the app, MyClass.string('stringPath') will return the translated component text. I need the app text to be updated when the user changes their language.
Binding doesn't work with static properties and methods (see this question for details Binding to static property).
In your case it's better to use the singleton pattern for resource manager and remove static from string and updateData:
MyClass.instance.string('stringPath')
and MyClass:
public static const instance:MyClass = new MyClass();

How to call some mxml function from class?

I have 2 files: Main.mxml with application and one MyObject.as.
I create the instance of MyObject in mxml and can call its every public function from mxml. But what if for some reason I need to call some function declared in mxml from MyObject class? How to do that? I thought that I could pass the reference to main.mxml class into this object but I couldn't figure out what exact class is it (it inherits Application, right, but what exact class is it?)
Thanks
It is of type Main (it takes on the name of the mxml file). You can add a static variable and getter method to it:
private static var _instance : Main;
public static function get instance () : Main {
return _instance;
}
Then let instance refer to this after the application is complete:
private function applicationCompleteHandler():void
{
_instance = this;
}
Don't forget to set applicationComplete="applicationCompleteHandler" in your <mx:Application> tag.
After that you can call Main.instance from anywhere in your program to access the methods and variables.
If you are instantiating the MyObject class in your Main.mxml, you could also accomplish access to a method in Main by passing the method as a Function into the object.
Suppose you have in Main.mxml the function:
private function doSomething():*{
...
}
With an appropriate setter in MyObject.as:
private var _mainFunction:Function;
public function set mainFunction(f:Function):void
{
_mainFunction = f;
}
Then you can pass the method when you instantiate the MyObject class in the mxml:
<*:MyObject mainFunction='doSomething'/>
And now you just call _mainFunction in the MyObject.as code whenever you need it.
Of course, Weltraumpirat's suggestion would be more efficient if you needed to access more than one method and/or variable on your Application.

Actionscript 3: Can someone explain to me the concept of static variables and methods?

I'm learning AS3, and am a bit confused as to what a static variable or method does, or how it differs from a method or variable without this keyword. This should be simple enough to answer, I think.
static specifies that a variable, constant or method belongs to the class instead of the instances of the class. static variable, function or constant can be accessed without creating an instance of the class i.e SomeClass.staticVar. They are not inherited by any subclass and only classes (no interfaces) can have static members. A static function can not access any non-static members (variables, constants or functions) of the class and you can not use this or super inside a static function. Here is a simple example.
public class SomeClass
{
private var s:String;
public static constant i:Number;
public static var j:Number = 10;
public static function getJ():Number
{
return SomeClass.j;
}
public static function getSomeString():String
{
return "someString";
}
}
In the TestStatic, static variables and functions can be accessed without creating an instance of SomeClass.
public class TestStaic
{
public function TestStaic():void
{
trace(SomeClass.j); // prints 10
trace(SomeClass.getSomeString()); //prints "someString"
SomeClass.j++;
trace(SomeClass.j); //prints 11
}
}
A static variable or method is shared by all instances of a class. That's a pretty decent definition, but may not actually make it as clear as an example...
So in a class Foo maybe you'd want to have a static variable fooCounter to keep track of how many Foo's have been instantiated. (We'll just ignore thread safety for now).
public class Foo {
private static var fooCounter:int = 0;
public function Foo() {
super();
fooCounter++;
}
public static function howManyFoos():int {
return fooCounter;
}
}
So each time that you make a new Foo() in the above example, the counter gets incremented. So at any time if we want to know how many Foo's there are, we don't ask an instance for the value of the counter, we ask the Foo class since that information is "static" and applies to the entireFoo class.
var one:Foo = new Foo();
var two:Foo = new Foo();
trace("we have this many Foos: " + Foo.howManyFoos()); // should return 2
Another thing is static functions could only access static variables, and couldn't be override, see "hidden".