サイトトップ

Director Flash 書籍 業務内容 プロフィール

Macromedia Flash非公式テクニカルノート

クラスのメソッド内でwithを使って指定したオブジェクトが参照されない

ID: FN0804001 Product: Flash Platform: All Version: CS3/ActionScript 3.0

問題
withステートメントを用いると、識別子に参照がないとき、指定したオブジェクト内をまず探して、値を得ようとします。ところが、クラスのメソッド内でwithステートメントを使うと、指定したインスタンスでなく、同名のローカル変数(Activationオブジェクト)やインスタンスメンバー(プロパティやメソッド)の値を取得してしまうことがあります。

たとえば、以下のクラスTest(スクリプト001)は、withステートメントでローカル変数(_array)に設定した配列を指定しているにも拘らず、参照なしにプロパティ(length)やメソッド(push())にアクセスすると、同名のインスタンスプロパティやインスタンスメソッドの値が得られてしまいます(図001)。Testクラスを試すには、クラス定義ファイルTest.asと同階層に保存したFlashムービー(FLA)ファイルのフレームアクションから、つぎのようにコンストラクタを呼出します。

// Flashムービー(FLA)ファィル: Test.asと同階層に保存
// タイムライン: メイン
// フレームアクション
var obj:Test = new Test();
スクリプト001■withで指定したインスタンスよりクラスのインスタンスが先に参照される

// ActionScript 3.0クラス定義ファイル: Test.as
package {
  public class Test {
    private var length:int = 100;
    public function Test() {
      // var length:int = 10;
      var _array:Array = new Array();
      trace(_array.length);   // 出力: 0
      with (_array) {
        trace(length);   // 出力: 100
        trace(push(0));   // 出力: 1000
      }
    }
    private function push(n:int):int {
      return 1000;
    }
  }
}

図001■withで指定した配列でなくインスタンスメンバーの値が[出力]される
図001

なお、上記スクリプト001のコメントアウトされているローカル変数設定のステートメントを有効にすると、インスタンスプロパティでなくこの変数値が先に参照されます。


原因
クラスのメソッド内で使われたwithステートメントは、指定したインスタンスより先にActivationオブジェクトとクラスインスタンス内の識別子を探しにいってしまうようです。ただし、インスタンスメンバーをpublic属性で指定すると、検索の対象からは外れます。ActionScript 3.0のバグだと考えられます[*1]

[*1] ActionScript 2.0では、このような現象は発生しません(図002)。

図002■ActionScript 2.0ではwithで指定した配列が正しく参照される
図001


対処法
withステートメントは使わないことをお勧めします[*2]

[*2]「withステートメントについて」は、ActionScript 2.0についての解説ですが、基本的に3.0にも当てはまります。


作成者: 野中文雄
作成日: 2008年4月27日


Copyright © 2001-2008 Fumio Nonaka.  All rights reserved.