gskinner.com: gBlog: FlashMX 2004 source code, news, reviews and opinions
Back to gBlog Main gskinner.com website: source code, portfolio, etc. contact Grant Skinner

Syndication
RSS 1.0
RSS 2.0


Subscribe
Enter your email address to be notified when posts are added.

Search

Resources
Conference Session Notes

Flash Blogs
Waxpraxis
Philterblog
W3Blog
Jonas Galvez
Josh Dura
Quasimondo
Flashguru
Sean Voisen
Colin Moock
Flazoom
Greg Burch
Pope De Flash
Peter Hall
Glyn Thomas
actionscript.com
Princess Pegg


Aggregators
Flog
FullAsAGoog
MXNA
Hall of Justhese


« OOP4AS2#5: Inheritance (extends and super) | Back to Main | More OOP4AS2 translations »

September 19, 2003


IMPORTANT NOTE: This is an old archive. It is only here to support outdated external links. To view the updated version of this archive, please go to the blog index, and search for the title of this document using the search form.

Passing arguments to super class's constructor
Posted by Grant
In AS2, you can pass parameters to a super class's constructor using super() . This is handy, but what if your constructor accepts an undefined number of parameters, and you want to pass them all to your super constructor (think of the Array class, for instance)? Sounds easy - you should just be able to use "super.apply(this,arguments)", right? Wrong...

BEGIN EXTENDED ENTRY

In AS2, you can pass parameters to a super class's constructor using super() like so:

class MySubClass extends MySuperClass {
   function MySubClass(p_param) {
      super(p_param);
    }
}

This is handy, but what if your constructor accepts an undefined number of parameters, and you want to pass them all to your super constructor (think of the Array class, for instance)? Sounds easy - you should just be able to use "super.apply(this,arguments)", right?

Wrong. Two things get in the way:
  1. The compiler does not interpret "super" as being a function, and will return "There is no method with the name 'apply'."
  2. Because the compiler can't find a call to super() in the sub class constructor (it isn't smart enough to understand super.apply()), it inserts an empty super() call at the beginning of the sub class constructor, so even if you get super.apply to work, the constructor will be called twice!


I wrestled with this issue for a bit, then talked it through with Jonas Galvez, who came up with a solution. It's a bit hackish, but it works! Here's what it looks like:

class MegaArray extends Array {
   function MegaArray() {
      super; // tricks the compiler
      __proto__.constructor.apply(this, arguments);
    }
}

Basically, it tricks the compiler into thinking we have called the super class's constructor, then we really call it using apply.

Just don't try spelling constructor as "contructor", or you'll spend 20 minutes wondering why the heck it doesn't work! :P

Nice work Jonas!


EDIT: Sometimes you look too hard and make things more complex than they have to be... It looks as though this will work too (thanks David):

class MegaArray extends Array {
   function MegaArray() {
      super.constructor.apply(this, arguments);
    }
}

Posted @ 02:16 PM by Grant | TrackBack


Comments

yo, nice discovery. played with it a lil and found super.constructor.apply(this, arguments); seems to work too.

Posted by: David at September 19, 2003 03:16 PM

super.constructor actually makes grammatical/logical sense as well. Nice.

Posted by: Peter Hall at September 20, 2003 07:16 PM

I have to say that this doesnt work at all for me, If I extend the Array class and then try and do what you describe above, then my array is empty.

Posted by: Chris Jenkins at September 22, 2003 03:15 AM

the same happened to me for array inheritance.
here's a work arround
[as]class myClass extends Array{
function WindowsAdmin(){
for(var i=0;i<arguments.length;i++){
this.push(arguments[i]);
}
}
}[/as]

Posted by: sangles at September 22, 2003 01:26 PM

Hi Sangles and Chris,

You must call the Array constructor, as follows:

class SuperArray extends Array {
    function SuperArray() {
        super.constructor.apply(this, arguments);
    }
}

Posted by: Jonas Galvez at September 25, 2003 10:37 AM

Jonas, it doesn´t work.
try:
var ma:MegaArray = new MegaArray(1,2,3,4);
trace(ma[2]);
the result is undefined, not 3.
The first approach doesn´t look to work either(?)
cheers,
Florian

Posted by: Florian Krüsch at September 26, 2003 01:00 AM

how about this,

super.constructor.apply(null,arguments);

that way the super constructor will execute in the super scope as opposed to "this" scope.

-Butt

Posted by: Butt Sparkler at September 26, 2003 01:49 PM

played with this recently... and its not working... i wonder what's causing this to work on some system and fail on others :(

Posted by: krist at October 2, 2003 01:58 AM

Doesn't work for me to ?
Is there a work around ?
Thanks

Posted by: Sam at October 22, 2003 10:08 AM

If the superclass is inherited from another class, will the super.constructor.apply instruction work, despite of the "constructor bug" ?!?

Posted by: LAlex at October 23, 2003 05:04 PM

http://chattyfig.figleaf.com/ezmlm/ezmlm-cgi?1:mss:90588

Posted by: Jonas Galvez at October 23, 2003 06:05 PM

super.constructor.apply(this, arguments);
works for me.
My superclass is not a subclass of any other class.
Thanks!

Posted by: mike at April 3, 2004 12:24 PM

Hosting by NetKeepers.ca | Powered by Movable Type 2.661
The text content of this blog is licensed under a Creative Commons License. Graphics are ©2003 Grant Skinner.