How do i refer to a get function as an object - actionscript-3

I'd like to reference a get function as a Function object rather than as the value that it returns.
Normally i would be able to simply refer to the function without parenthesizes like so:
private function getFoo():int {
return 0;
}
trace(getFoo); // traces function
But the whole point of get functions is that you can call the function without the parenthesizes, so i just get a return of 0 if i do this:
private function get foo():int {
return 0;
}
trace(foo); // traces 0
Is there be any way at all to grab a reference to the foo function object?

Your first example gets a reference to the function (as it traces Function).
There is no way to get a reference to a getter, as getters are not simple functions, but a representation of a (custom) property of that object. They are not meant to work as a standard ones and so they are not meant to be referenced.
I cannot imagine why would you want to get a reference to that getter? And also, getters are not meant to be used only because you can skip those two symbols ()..

Related

Is it not possible to get the arguments array from a static method?

I'm trying to get the reserved keyword arguments array from inside a static method and I'm getting this error:
1042: The this keyword can not be used in static methods. It can only
be used in instance methods, function closures, and global code.
Here is my code:
public static function doSomething(message:String, ...Arguments):void {
var object:Object = this.arguments.caller;
}
If I take the this keyword out then I get the following error:
1120: Access of undefined property arguments.
this is reserved to reference the current instance of a class which unfortunately doesn't exist inside a static function (since static function is not tied to an instance).
You could try using the new rest keyword if you want to pass in an unknown number of arguments:
ActionScript 3.0 includes a new ...(rest) keyword that is recommended instead of the arguments class.
However if you want it just to get the caller function:
Unlike previous versions of ActionScript, ActionScript 3.0 has no arguments.caller property. To get a reference to the function that called the current function, you must pass a reference to that function as an argument. An example of this technique can be found in the example for arguments.callee.
public function test() {
doSomething("Hello", arguments.callee);
}
public static function doSomething(message:String, caller:Function):void {
var object:Object = caller;
}
You could get the arguments of a static method. From the documentation:
Within a function's body, you can access its arguments object by using the local arguments variable.
You do not need the this keyword, this references to the Class instance instead to the function itself:
public static function doSomething():void {
return arguments;
}
Next you can access to the arguments calling the static method:
var arguments:Object = MyClass.doSomething();
trace( arguments.callee );
But remember, like #MartinKonecny said, in AS3 is better use the ...rest keyword or pass a function reference as an argument.
The arguments object is available in static functions but is not available when using the ...rest parameter.
Use of this parameter makes the arguments object unavailable. Although
the ... (rest) parameter gives you the same functionality as the
arguments array and arguments.length property, it does not provide
functionality similar to that provided by arguments.callee. Make sure
you do not need to use arguments.callee before using the ... (rest)
parameter.
Take out the ...rest parameter and the arguments object appears.
Also, the this keyword is not always necessary.
method.apply(this, args);
may throw an error in a static function but the parameter is optional so this also works:
method.apply(null, args);
More on the rest keyword.

calculation under class as3

I am absolutely a beginner in as3; I am really trying to understand how as3 works. I wrote a simple function which will multiply one number (please see the following code). I want to multiply 9 with 5 and trace it but it's not multiplying. Can anyone help me?
package {
import flash.display.MovieClip;
public class main extends MovieClip {
var xyz:int=9;
public function main() {
// constructor code
mAth(xyz);
trace(xyz);
}
protected function mAth(xyz:int):int{
return(xyz*5);
}
}
}
You call the function "mAth" but don't use the results. try
trace(mAth(xyz));
to see the results of the function call.
Is there a specific reason why you pass an internal variable to a function? You can access xyz without passing the value to the mAth function.
It's a correct answer overall but it's not the main reason why trace is not showing the expected results and since the user wants to understand the given answer does not supply a why to a perfectly valid operation.
Here is a better one:
Primitive objects in AS3 are passed by value not by reference. Those are numbers and strings. When you pass your variable xyz to your function you would expect it to be modified like in some other language but since only the value it represents is passed your variable is not modified and stay at 9. This is the default behavior of AS3 and it cannot be overridden. So you just have to remember that primitive objects in AS3 when passed as parameters in methods/functions are only passed by value and as a result do not see their value change.
in your case:
var xyz:int=9;
var result:int = mAth(xyz);
//xyz is still 9 since only its value is passed to the method
//result is 45 since it computes and return the value passed as parameter

AS3 : What is the context of 'this' in an anonymous function?

In this example:
public function Roulette() {
new QuickLoad(url, function (o:*):void {trace(this);});
}
when QuickLoad instance does its stuff, it calls the anonymous function. One would think that this is Roulette. But no, it turns out to be the anonymous function's caller, which is QuickLoad.
This is weird to say the least, say how am I supposed to pass the "correct" this (i.e. Roulette instance) inside the anonymous function if I don't do it the normal way?
Just save the outer this instance under a different name so that it is preserved:
public function Roulette() {
var rouletteThis = this;
new QuickLoad(url, function (o:*):void {trace(rouletteThis);});
}
There is a way to call a function with an alternate this pointer, but since your function is called from within new QuickLoad(), you need to alter that call statement, and pass your this as Roulette into the constructor. Your new QuickLoad object is unaware of its surroundings, and even the caller of the constructor is unknown to it. Thus, you need to make it aware, pass a this pointer from Roulette() to QuickLoad(), AND call the function from QuickLoad with passing an alternate this pointer.
public function QuickLoad(url:String,caller:Object=null,callback:Function=null) {
// initialization code
if (callback!=null) {
if (caller!=null) callback.apply(caller,[o]);
else callback.apply(this,[o]);
}
}
...
public function Roulette() {
new QuickLoad(url, this, function (o:*):void {trace(this);});
}
Function::apply() manual.
You can also use call() method, if your argument array has fixed length. callback.call(caller,o);
Generally, in this context, this refers to an object. To quote a rather infamous acronym: INABIAF (It's not a bug, it's a feature), LOL. So, yes, the object instance QuickLoad that is calling the function is going to be what this looks at by default.
There is an exception I know of (out of many, I'm sure)...you can get anything...variable, function, object, whatever, via this["Name of Object"]. But that's an aside.
There ARE other workarounds, I'm sure, which may or may not be practical for your purposes. This is one way of passing a function, out of many, and it's the one I use the most.
Functions do not have instances. They're not objects. If you want to send a function as an argument to another function, you simply pass it, as follows in this rather weird example.
//This function accepts a function as an argument.
function bridgeOfQuestions(person:String, response:Function):void
{
if(person == "King Arthur")
{
response("What is the average airspeed velocity of an unladen swallow?");
}
else
{
response("What is your favorite color?");
}
}
//This is the function we're going to pass.
function askQuestion(question:String):void
{
trace(question);
}
//Here, we call bridgeOfQuestions and pass it the askQuestion function.
//NOTE: Leave off the parenthesis on the function being passed!
bridgeOfQuestions("Sir Lancelot", askQuestion);
bridgeOfQuestions("King Arthur", askQuestion);
EDIT: If it is just the name you're passing, a function is a function permanently. It doesn't change, unlike an object, and as I said, it doesn't have instances. Therefore, if you merely want to print out the name of the function, you'd only use trace("Roulette").

Function.call(someInstance,args) for methodes. Ignores first arg

In as3 there is a flexible way to change object instance, when calling it.
call or apply members of Function object can be called with specific first arg, and reference say us, that this first arg will be "this" pointer inside function. But i've found it wrong.
I'v write little test, listed below.
public class Test
{
private var name:String = "default";
public var test3:Function = test;
public var test2:Function = function()
{
trace(this.name);
}
public function Test(name:String)
{
this.name = name;
}
public function test():void
{
trace(this.name);
}
}
and tested it.
var tmp:Test = new Test("default");
tmp.test(); //out default
tmp.test.call(new Test("new")); //out default
tmp.test2(); //out default
tmp.test2.call(new Test("new2")); //out new2
tmp.test3(); //out default
tmp.test3.call(new Test("new3")); //out default
So, in anonymous function call we can get right output, but not in case of member function.
maybe it's becouse of ambiguous "this" pointer, that should reffer real object instance for correct work, maybe smth else. I dont now, and as3 reference didnt't describe smth about it.
Finally list of questions:
Why so? By me, it's very strange, and looks like undefined behaviour;
How i can achieve that functionality? How to deceive test function like anonymous one? Isn't it call methode target?
It isn't very important, but I'll be glad any good answer. Thanks!
P.S. sorry for my English.
//EDITED: added this statement to all "name" references. Nothing changes.
When invoking the [[Call]] property, the behavior is different for
different types of closures. A closure is an object that contains a
reference to a method, and the [[Call]] property acts differently
depending on whether it is a function, method, or class closure. A
function closure is one that is of a global method that isn't
associated with any instance of a class. A method closure contains an
instance method of a class, and will always remember its original
"this" value.
If the closure is a function closure, then the first argument passed
to [[Call]] is passed on to the method and gets used as the "this"
value. If the first argument is null or undefined, then the global
object will be used as the "this" value for the method.
If the closure is a method closure, then the first argument of
[[Call]] will be ignored, and the saved "this" value for the method
closure will be passed to the method as the first argument. A method
closure records what its original "this" value was and always uses
that instead of the first argument to [[Call]].
If the closure is a class closure, and there is 1 argument passed to
[[Call]] (in addition to the "this" argument), then the call is
treated as a type conversion, and the argument will be coerced to the
type represented by the closure.
http://learn.adobe.com/wiki/display/AVM2/2.4+Method+invocation+notes

Referencing getter/setter functions in actionscript 3

How does one get a reference the the getter and setter functions in actionscript 3?
if a method is defined on the calls, e.g.
public function blah():String { ...}
I can get a reference to it by just saying blah or this.blah
How do get a reference to
public function get blah2():String {}
public function set blah2(b:String):void {}
Thanks!
Original response:
Unfortunately, you will not be able to store references to those as functions. The getter and setter methods are actually built around the idea that you shouldn't be able to and they therefore function as a property.
Is there a reason that you need to reference the functions specifically?
The comment I'm responding to:
I want to dynamically add external interface methods based on custom metadata tags, e.g. [External]. I was able to do this for the regular methods, but I'm trying to extend this to getter/setters as well. To do this, I need to get a reference to the function dynamically, so I can execute it with the right args using the apply function.
I think you're better off using a multi-step approach in that case. Since getters and setters function as a property and not a method, it would make sense to test to see if it is a property and then simply assign it a value directly. Would you be able to use this:
if( foo.blah2 is Function )
{
foo.blah2.apply( foo, arr );
}
else
{
foo.blah2 = arr[ 0 ];
}