ActionScript - Overriding Method Without Matching Signature? - actionscript-3

when extending a class, is it impossible to override a method without also matching the parameters?
for example, i'd like to use the method's name, in this case it's a socket extension and the method i want to override is connect. however, i want to request additional parameters that the stock connect function does not request.
is the only alternative to create my own connect-like method with my own parameters, call super.connect from this function and override the stock connect function to throw an error if it's called?
that all kind of sounds like a train wreck.

Function overloading is not supported in ActionScript (however Darron Schall demonstrated some kind of pseudo overloading in this article).
I think in your case it's only left over to create your own connectEx method.

Sadly, overloading is not supported. As a next best option, you could consider optional arguments. This would allow you to pass as few or as many params as you want to a method. The method would receive these params in an array and you could handle them however you want from that point on.
Here's how a method using optional params would look:
function someMethod(...params):void
{
for(var i:int = 0 ; i < params.length ; i++ )
{
trace("parameter: " + params[i]);
}
}
You can read more about optional parameters here.

Related

Can a pure function call external function?

Can a pure function call an external method?
for example:
class Dog {
function jump(name) {
return "a dog named " + name + " jumped!"
}
function jumpTwice(names) {
var result = [];
for (var i = 0; i < 2; i++) {
result.push(jump(names[i]));
}
return result.join("\n");
}
}
can jumpTwice() be considered as a pure function?
When you can
A pure f function can call any other function/method g0...gn.
But g0...gn must be pure as well.
When you cannot
As soon as you get a pure function f and you invoke a non pure function g from within f, then f is no longer pure.
Yes, it is pure. It doesn't mutate any global state nor gives different results for same input.
In the specific case you give, yes. But what you have there is a method and methods require extra care.
Pure functions always give the same result for any given input, no matter what the current program state.. Methods can be viewed as functions which are passed their object as a hidden parameter. To be pure, the method must not access any implicit state (nor may they call any other methods/functions which are susceptible to implicit state). This means also not using any object fields which contain implicit state. The comments discussion hopefully gives an example of how to judge that context.
It's not enough to shun mutable fields - the value in immutable fields field must be knowable/predictable . For example, if an object contained an immutable private field which was given a random number on object creation, any method which used that value to compute it's output would be impure.
On the other hand, if your Dog class had an immutable name field which was set on object creation, then methods which used that field can be considered pure (unless something else disqualifies them).
EDIT
It would have been helpful to say that "side effect" and "purity" is contextual (as discussed in the comments). Which is what I didn't entirely clearly allude to by the use of the words "knowable" and "predictable". The comments discussion illustrates the importance of knowing the context.

Actionscript: How exactly does ExternalInterface.addCallback() work?

I'm pretty new to ActionScript, but not new to either object oriented or procedural languages in general. ActionScript's particular combination of features from both categories, however, confuses me.
Specifically, I'm confused about the mechanism of ExternalInterface.addCallback(). The method signature is:
public static function addCallback(functionName:String, closure:Function):void
Of particular interest is the closure parameter, which has the following documentation:
closure:Function — The function closure to invoke. This could be a free-standing
function, or it could be a method closure referencing a method of an
object instance. By passing a method closure, you can direct the
callback at a method of a particular object instance.
I take the above to mean that closure only be a function (not a method), which may or may not be a closure containing a method call from an instantiated object. So I get confused when I see code like this (taken from the same documentation page):
public class ext_test extends Sprite {
function ext_test():void {
ExternalInterface.marshallExceptions = true;
ExternalInterface.addCallback("g", g);
try {
ExternalInterface.call("throwit");
} catch(e:Error) {
trace(e)
}
}
function g() { throw new Error("exception from actionscript!!!!") }
}
The above code inserts in to addCallback, a non-static method of ext_test without wrapping it in a closure containing an instantiated ex_test object.
The method contains trivial code, but what if it were to have statements containing member variables and the like? How would the method be evaluated when it has no parent object?
Furthermore, (since the addCallback seems to allow the passing of arbitrary methods) the documentation makes no mention on the effect access modifiers have on the passed methods, if any. If I label a method private, am I still able to pass it to addCallback? What's the deal?
I'd appreciate it if anyone can help me wrap my head around this.
If your concern is to know in what context the method you passed will be executed, this is simply the context in which you attached it.
The doc's jibber jabber simply means that there are several kinds of function in AS3 and the runtime. "Free-standing" function refers to what you usually call an anonymous function - that still preserves the context in which they were defined :
var anonymous:Function = createAnonymous();
trace(anonymous()); // 123
function createAnonymous():Function {
var internalStuff:Number = 123;
var func:Function = function():Number {
return internalStuff;
}
return func;
}
Methods closures are instances of your classes' methods, the same way objects are instances of these classes. So, when you pass a method closure to ExternalInterface.addCallback(), you'll be safe about the context (i.e. member variables) when it will be invoked.
Woops. Totally forgot the that in all the examples I've seen, addCallback is being executed in the context of a constructor, so the method references passed to it have a context to execute under.
As such, access modifiers don't matter since everything in a class can be seen by the class.

Is there a way to avoid using 'call' in Coffeescript?

I'm writing a simple Twitter client to play with coffeescript. I have an object literal with some functions that call each other via callbacks.
somebject =
foo: 'bar'
authenticateAndGetTweets: ->
console.log "Authorizing using oauth"
oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails)
oauth.authorize( this.afterLogin.call this )
afterLogin: ->
this.getTweets(this.pollinterval)
This code works perfectly. Edit: actually this.afterlogin should be sent as a callback above, not ran immediately, as Trevor noted below.
If, within authenticateAndGetTweets, I removed the 'call' and just ran:
oauth.authorize( this.afterLogin )
and don't use 'call', I get the following error:
Uncaught TypeError: Object [object DOMWindow] has no method 'getTweets
Which makes sense, since 'this' in afterLogin is bound to the thing that initiated the callback rather than 'someobject' my object literal.
I was wondering if there's some magic in Coffeescript I could be doing instead of 'call'. Initially I thought using the '=>' but the code will give the same error as above if '=>' is used.
So is there a way I can avoid using call? Or does coffeescript not obviate the need for it? What made '=>' not work how I expected it to?
Thanks. I'm really enjoying coffeescript so far and want to make sure I'm doing things 'the right way'.
As matyr points out in his comments, the line
oauth.authorize( this.afterLogin.call this )
doesn't cause this.afterLogin to be called as a callback by oauth.authorize; instead, it's equivalent to
oauth.authorize this.afterLogin()
Assuming that you want this.afterLogin to used as a callback by oauth.authorize, megakorre's answer gives a correct CoffeeScript idiom. An alternative approach supported by many modern JS environments, as matyr points out, would be to write
oauth.authorize( this.afterLogin.bind this )
There's no CoffeeScript shorthand for this, partly because Function::bind isn't supported by all major browsers. You could also use the bind function from a library like Underscore.js:
oauth.authorize( _.bind this.afterLogin, this )
Finally, if you were to define someobject as a class instead, you could use => to define afterLogin such that it's always bound to the instance, e.g.
class SomeClass
foo: 'bar'
authenticateAndGetTweets: ->
console.log "Authorizing using oauth"
oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails)
oauth.authorize(this.afterLogin)
afterLogin: =>
this.getTweets(this.pollinterval)
someobject = new SomeClass
you can put a lambda in the function call like so
auth.authorize(=> #afterLogin())
You have to use either the call or apply methods because they set the scope of the function (the value of this). The error results because the default scope is the window object.

why overloading not support in Actionscript?

Action script is developed based on object oriented programming but why does it not support function overloading?
Does Flex support overloading?
If yes, please explain briefly with a real example.
As you say, function overloading is not supported in Action Script (and therefore not even in Flex).
But the functions may have default parameters like here:
public function DoSomething(a:String='', b:SomeObject=null, c:Number=0):void
DoSomething can be called in 4 different ways:
DoSomething()
DoSomething('aString')
DoSomething('aString', anObject)
DoSomething('aString', anObject, 123)
This behavior maybe is because Action Script follows the ECMA Script standard. A function is indeed one property of the object, so, like you CAN'T have two properties with the same name, you CAN'T have two functions with the same name. (This is just a hypothesis)
Here is the Standard ECMA-262 (ECMAScript Language Specification) in section 13 (page 83 of the PDF file) says that when you declare a function like
function Identifier(arg0, arg1) {
// body
}
Create a property of the current variable object with name Identifier and value equals to a Function object created like this:
new Function(arg0, arg1, body)
So, that's why you can't overload a function, because you can't have more than one property of the current variable object with the same name
It's worth noting that function overloading is not an OOP idiom, it's a language convention. OOP languages often have overloading support, but it's not necessary.
As lk notes, you can approximate it with the structure he shows. Alternately, you can do this:
public function overloaded(mandatory1: Type, mandatory2: Type, ...rest): *;
This function will require the first two arguments and then pass the rest in as an array, which you can then handle as needed. This is probably the more flexible approach.
There is another way - function with any parameters returns anything.
public function doSomething(...args):*{
if(args.length==1){
if(args[0] is String){
return args[0] as String;
}
if(args[0] is Number){
return args[0] as Number;
}
}
if(args.length==2){
if(args[0] is Number && args[1] is Number){
return args[0]+args[1];
}
}
}
You can't overload, but you can set default values for arguments which is practically the same thing, but it does force you to plan your methods ahead sometimes.
The reason it doesn't is probably mostly a time/return on investment issue for Adobe in designing and writing the language.
Likely because Actionscript looks up functions by function name at runtime, rather than storing them by name and parameters at compile time.
This feature makes it easy to add and remove functions from dynamic objects, and the ability to get and call functions by name using object['functionName'](), but I imagine that it makes implementing overloading very difficult without making a mess of those features.

Checking anonymous function signatures at runtime (reflection) in AS3

Is there any way to have a look at signatures of anonymous functions in ActionScript 3 during runtime?
I would like to validate Function objects passed in as arguments to other functions and make sure that they accept the correct number of arguments (with the correct types) and return a value of the correct type.
flash.utils.describeType() doesn't seem to return this info for anonymous functions.
It doesn't look like the runtime allows you to reflect on anonymous functions, which is a shame.
Anonymous functions are (perhaps by definition) marked as dynamic. If you pass an incompatible type into an anonymous function, no error is thrown. Any type mismatches will be silently cast as best they can. Passing something like "minotaur" as a uint parameter will yield 0 (zero), for example.
If you REALLY want to over-engineer it, you could get all OO on it. Instead of accepting anonymous functions, you could declare an interface which contains the appropriate function signature, and accept objects that implement that interface.
public interface IFancyCallback {
public function fancyFunction(frog:Frog, princess:Girl):UsefulReturnType;
}
And your function would just have to be packaged up in an object:
public class ConcreteCallback implements IFancyCallback {
public function fancyFunction(frog:Frog, princess:Girl):UsefulReturnType {
princess.kiss(frog);
return new UsefulReturnType("jabberwocky");
}
}
Could have the potential to create a lot of code overhead. Depends how many callbacks you intend to have, who's going to be making them, and what how serious it would be if the anon function's signature was incorrect.
Can you share any more about the problem you're trying to solve?
As a rough approximation you can check the number of parameters using length property, e.g.:
function doStuff(callback:Function) {
trace(callback.length);
}
I'm not aware of any way to enumerate the arguments of an anonymous functions; you can of course validate ex-post catching ArgumentError.