AS3の*型の問題点とその代替案 〜その1.*型は問題点が多い〜

目次

長くなったので3部構成

静的に解決出来るところはすべてそうするべき

私は動的型付け言語は嫌いだ。どれくらい嫌いかというと、RubySchemeも、Pythonも、動的型付けという理由だけで、勉強しようとしないぐらい。
動的型付け言語なんて滅びればいいのに。

AS1のを使っていた頃に、嫌というほど味わったのが私の中では大きい。(しかもAS1は弱い型付けだ!)

AS2、AS3とバージョンが上がり、Javaのように静的型チェックをしてくれるようになった。
しかしながら、AS3では*型やオブジェクトリテラル、dynamicクラスを使うことによって動的型付けでもコーディングすることは可能だ。
これらは動的にしか解決できない場合に使用すると大きな効果が期待される。が、それ以外の場面では、型(クラス)をきちんと作り、静的に解決すべきた。

オブジェクトリテラルが使われている例

ProgressionTweenerPapervision3DなどAS3ライブラリの一部では*型が結構使われていたりする。
これはオブジェクトリテラルが短く書けるのでよく使われているのだが、動的型付けであるが故に弊害が出てくる。

Tweenerの例

package {
	import flash.display.Graphics;
	import flash.display.Sprite;
	import caurina.transitions.Tweener;
	public class FlashTest extends Sprite {
		public function FlashTest() {
			var box:Sprite = new Sprite();
			var g:Graphics = box.graphics;
			g.beginFill(0xFF0000);
			g.drawRect(0,0,10,10);
			g.endFill();
			addChild(box);
			Tweener.addTween(box,{
				x:100,
				y:100,
				delay:0.5,
				time: 1,
				scaleX:5,
				scaleY:4
			});
		}
	}
}

Tweener.addTween()の第二引数にオブジェクトリテラルが使われている。
ここにどのような問題が孕んでいるのか?

問題1.静的型チェックが行われない

オブジェクトリテラルを使用した場合、静的型チェックが行われない。
これはscaleXをscalexというふうにタイピングミスした時にはコンパイラはエラーを出してくれない。
また、scaleX:"10"のように、本当はNumber型を入れるべきところに、String型を入れた時もコンパイルエラーにならない。
つまりオブジェクトリテラルを使うということは静的型付けの一番の長所を使わないことになる。

問題2.*型では何を代入すればいいか分からない

function foo(obj:*):void{
	//code
}

こんなコードがあった場合、あなたはobjに何を入れればいいかわかりますか?
objに型さえついていれば、その型を代入すればいいということが理解出来るだろう。
しかし型が*の場合、ドキュメントを読まなければ理解できない。
Stringのメソッド(match)などの引数が*型のせいでいつもググって調べているのは私だけではないはず。

問題3.*型ではコード補完が出ない

コード補完の恩恵は美味しい。FlashDevelopを使っている人はよくわかっているだろう。
オブジェクトリテラルではそういった恩恵は受けられない。
どんなメンバがあったか、わざわざドキュメントまで探しに行かなければならない。

問題4.*型では実行速度が遅い

これは上の3つほどには気にならない問題。
だが、何千回もループして使用た場合パフォーマンスのボトルネックになりうる。


つづき
その2.オブジェクトリテラル