Hatena::ブログ(Diary)

妄想宝箱

2009-08-28

[]try catchでスコープが可能!?

AS3ではブロック単位のスコープは無くて、スコープが欲しい場合は、関数クロージャでくくったりする。でもそれ以外にも方法があったらしいね。

偶然にもtry catchでもスコープがあることを発見した。

なんだこれ?

package 
{
	import flash.display.Sprite;
	import flash.text.TextField;	
	public class Main extends Sprite 
	{
		public function Main():void 
		{
			var xs:Array = [];
			try { throw 0; } catch (i:int) {
				for (; i < 5; i++ )
				{
					xs.push(i);
				}
			}
			var sum:int = 0;
			try { throw 0; } catch (i:int) {
				for (; i < xs.length; i++ )
				{
					sum += xs[i];
				}
			}
			var tf:TextField = new TextField();
			addChild(tf);
			tf.text = "sum" + sum;
			//trace(i);//コンパイルエラー
		}
	}
}

http://wonderfl.net/code/47bb13e129e7eee92a0a556bbe430b78bb8cb29d#251374

iに注目。

catch(i:int)で宣言しているiのスコープはcatchの中になっているっぽい。

つまりcatchの外からはiは見えない。

何でこうなるかはわかんない。仕様なのか?バグなのか?


ひとまずこれで、これで関数内でスコープを自由自在に使いこなすことが出来るね!

...ってことにはならない。


そもそも例外を例外以外で使おうとするなんて、問題外。

可読性めっちゃ悪いし。


例えば、スコープの付いた変数を2個定義しただけでも、

try { throw 0; } catch (i:int) {
	try { throw 0; } catch (j:int) {
		for (i=0; i < 5; i++ ) {
			for (j=0; j < 5; j++ ) {
				trace(i, j);
			}
		}
	}
}

と、ネストがひどい。

面白い機能だけど、くれぐれも遊び以外では使わないように!

追記

どうやらこれはECMAScripの仕様らしいです。

ECMA262規格で決められた仕様です。AS3はECMA262の拡張言語なのでECMAの仕様は踏襲していると思います。JavaScriptも同様だけど、これが正しく実装されていない処理系もあったりします(特にJScript)。

tako222tako222 2009/08/29 02:22 >つまりcatchの外からはiは見えない。
>何でこうなるかはわかんない。仕様なのか?バグなのか?

C++でも同じみたいですけど、これって普通じゃないんですか?

coppieeecoppieee 2009/08/29 12:11 >C++でも同じみたいですけど、これって普通じゃないんですか?
C++トAS3ハ別言語ダヨ。関係ナイヨ。

mindcatmindcat 2009/08/29 12:41 > 何でこうなるかはわかんない。仕様なのか?バグなのか?
ECMA262規格で決められた仕様です。AS3はECMA262の拡張言語なのでECMAの仕様は踏襲していると思います。JavaScriptも同様だけど、これが正しく実装されていない処理系もあったりします(特にJScript)。

eternalharvesteternalharvest 2010/01/01 10:35 ECMA262の仕様のことは、よくわかりませんが仕様にかいてあるからそうなんだろうとは思いますが、try 〜 catch ステートメントの catch は割り込みによって実行されるはずなので根本的にスタックが違うんじゃないかな。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/coppieee/20090828/1251477848
Connection: close