# \[Tip\] Skipping super() - Interesting behavior

**URL:** <https://forum.kirupa.com/t/tip-skipping-super-interesting-behavior/321163>\
**Category:** flash\
**Created:** [April 12, 2011, 11:47am UTC](https://forum.kirupa.com/t/tip-skipping-super-interesting-behavior/321163 "2011-04-12T11:47:54Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![krilnon](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/krilnon/32/34_2.png) [@krilnon](https://forum.kirupa.com/u/krilnon)\
**Post date:** [April 12, 2011, 11:47am UTC](https://forum.kirupa.com/t/tip-skipping-super-interesting-behavior/321163/1 "2011-04-12T11:47:54Z")

</div>

The AS3 docs state that `super()` is called no matter what. This has basically been the common wisdom, too.

> [@AS3LR](#):
>
> Note that the superclass constructor is always called, whether or not you call it explicitly. If you do not explicitly call it, a call with no arguments is automatically inserted before the first statement in the subclass constructor body.

This isn’t strictly true. It turns out that you can avoid calling the superconstructor by throwing an error:

```php
// this is really AS3
class Base {
	public function Base(){
		trace('Base constructor');
	}
}

class Subclass extends Base {
	public function Subclass(){
		try {
			Error.throwError(Error, 0);
			super();
		} catch(err:Error){}
	}
}

```

If you take the above code and (elsewhere) construct a `new Subclass()`, you’ll notice that you never get the trace that’s supposed to occur.

(Note: It’s fairly tricky to get that call to `super()` to be accepted without using Error.throwError, because there are some conditions on where you can use `super()`: “1201: A super statement cannot occur after a this, super, return, or throw statement.” I think those guards are there to enforce that the call to `super()` is made once and only once, although I’ve demonstrated that it isn’t being enforced _well_.)

You can even defer the call to `super()` until an arbitrary amount of time later:

```php
// really AS3 still
class Base {
	public function Base(){
		trace('Base constructor');
	}
}

import flash.utils.*;

class Subclass extends Base {
	private var konstructor:Function;
	
	public function Subclass(){
		try {
			if(!konstructor){
				konstructor = arguments.callee;
				setTimeout(konstructor, 5000);
				Error.throwError(Error, 0);
			}
			super();
		} catch(err:Error){}
	}
}

```

Now, you might be wondering what good could ever possibly come of this. I was wondering the same thing, until I remembered the classic “null-stage” problem. If you’re not familiar with it, it’s an error that often occurs when you’re using somebody else’s compiled code that assumes that DisplayObject#`stage` is going to be defined when the class is instantiated. In actuality, `stage` will be `null` sometimes, such as when an SWF is loaded into another SWF, and what was originally the document class is now just another random DisplayObject that may not even be on a display list linked to the stage (which happens when the Loader was never added to the stage).

This whole _skipping `super()`_ approach sort of finds a solution for this problem, although it’s not as complete as I wish it could be. It still can’t solve the external SWF stage-null problem due to limitations on how you can mix the definitions that are included in a Loader’s LoaderContext’s ApplicationDomain.

However, you can solve a somewhat wimpier null-stage problem, where you just have an SWC in which there’s a class that assumes its stage is defined:

```php
// AS3

/*
    Assume that this is compiled into an SWC and you lose the source code later.
*/

package {
	import flash.display.*;
	
	public class NullStage extends Sprite {		
		public function NullStage() {
			trace('I\'m about to access a null stage, haha!');
			stage.scaleMode = StageScaleMode.NO_SCALE;
			trace('Success');
		}
	}
	
}

```

Trying to use this class would normally result in an unfixable error! So, the solution is to create a wrapper subclass that takes advantage of the trick that I’ve been describing. You _could_ just wrap a `try` block around the call to `super()` in this subclass so that the stage access wouldn’t break your own code, but then you would never get to execute the code in NullStage’s constructor. You definitely want to execute that code, because it’s the whole reason you’re using the NullStage SWC instead of rewriting the code yourself.

So, you need to _defer_ the call to NullStage’s constructor like this:

```php
// AS3
import flash.events.*;

class NullStageWrapper extends NullStage {
	
	public function NullStageWrapper(){
		try {
			if(!stage){
				addEventListener(Event.ADDED_TO_STAGE, arguments.callee);
				Error.throwError(Error, 0);
			}
			super();
		} catch(err:Error){}
	}
}

```

Now, whenever you get around to adding NullStageWrapper to the root display list, NullStage will have its constructor called for the first time and it should behave the same as the original SWC author intended, and you won’t have had to decompile, post-process, or rewrite any code!

Admittedly, that’s a bit of a stretch of a use case. From my perspective, it was neat enough just to notice that you can get away without calling constructors despite all of the documentation stating that it was quite necessary.

It’s worth noting that instance initialization functions, which include the non-static code that’s within `class` blocks but not inside of any function, are still called unavoidably. Since they’re called before constructors are, you don’t get a chance to cancel their execution with custom code of your won.

I also found that this behavior reveals a rather bad bug in Flash Player, where you can crash the player immediately if you subclass Dictionary and cancel the call to its constructor. I logged the bug [in Tamarin and in Adobe’s bugbase as FP-6626 (if it’s ever made public). You can [URL=“http://temp.reclipse.net/DictionaryConstructBug/DictionaryConstructBug.html”]test the bug here](https://bugzilla.mozilla.org/show_bug.cgi?id=649276) to see if it crashes your player too! :trout:

Let me know what you think; I’m curious to see if there are any other neat or weird things that you can do with this.
