kagamihogeの日記

kagamihogeの日記です。

ActionScript のクラス初期化子

詳説 ActionScript 3.0 をダラダラと読んでいます。何かと Java と比べて読んでしまうのだけど、クラス初期化子の書き方が(Java と比べて)ちょっと面白かったので、実験など含めたメモ。

で、クラス初期化子の書き方と使い方。

まず、クラスを使う側のテキトーな Application を用意。ボタン押すとクラス初期化子が走ります。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
    <mx:Script>
        <![CDATA[
            import classinit.TestClassInitlize;
            private function clicked():void {
                var  clsInitilize:TestClassInitlize = new TestClassInitlize();
            }
        ]]>
    </mx:Script>
    <mx:Button label="ボタン" click="clicked()"/>
</mx:Application>

次に、クラス初期化子でテキトーな処理をするクラス。

package classinit
{
    public class TestClassInitlize
    {
        public static var d:Date;
        public static var s:String;
        private static var sec:Number;
        
        d = new Date();
        sec = d.getSeconds();
        trace(sec);
        trace(d);
        
        public function TestClassInitlize()
        {
            trace("TestClassInitlize()");
        }
    }
}

恐ろしいというか面白いというか、class のスコープ内に書いてあるコードがクラス初期化子になる……ぽい? キモいのは、こう書いても同じ動作になる。

package classinit
{
    public class TestClassInitlize
    {
        public static var d:Date;
        public static var s:String;
        private static var sec:Number;
        
        d = new Date();
        sec = d.getSeconds();
        trace(sec);
        
        public function TestClassInitlize()
        {
            trace("TestClassInitlize()");
        }
        //?!
        trace(d);
    }
}

すごいんだかキモいんだか判断に迷うけど、キモいと思います。

カッコをつけることで、見た目のキモさは若干やわらぐかな?

package classinit
{
    public class TestClassInitlize
    {
        public static var d:Date;
        public static var s:String;
        private static var sec:Number;
        
        {
            d = new Date();
            sec = d.getSeconds();
            trace(sec);
            trace(d);
        }
        
        public function TestClassInitlize()
        {
            trace("TestClassInitlize()");
        }
    }
}

もちろん条件分岐なんかを入れることも可能。

package classinit
{
    public class TestClassInitlize
    {
        public static var d:Date;
        public static var s:String;
        d = new Date();
        private static var sec:Number;
        sec = d.getSeconds();
        trace(sec);
        //無意味に分岐してみたりするテスト
        if (sec > 30) {
            s = sec + "> 30";
        } else {
            s = sec + "<= 30";
        }
        trace(s);
        
        public function TestClassInitlize() {
        }
    }
}

一応、意図どおりに動作する。

ところで、このクラスをコンパイルすると if (sec > 30) { の行で SignatureGenerationFailed で Unreachable Codepath うんぬんと Warning が出てくる。なんのこっちゃ? とググってみたけど、原因はよくわからない。 によると Flex SDK のバグ扱いされている。ただ、This should be resolved by revision 6589. とか書かれてるけど、I had the same problem with SDK 3.3.0.4852 とか追記してる人がいるんだよなぁw 3.4 では直ってるんですかね? まーたいしたこっちゃなさそーなバグなんで、別にいいっちゃいいんだけども。