サイトトップ

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

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

黙示的なsetメソッドの代入式でgetメソッドが呼出される

ID: FN0402005 Product: Flash

Platform: All
Version: MX 2004

1. 現象
ActionScript 2.0クラスで黙示的なset/getメソッドを定義して、代入式によりsetメソッドを呼出すと、getメソッドの呼出しも行われます。

// ActionScript 2.0クラス定義ファイル: GetterSetterTest.as
class GetterSetterTest {
  var _myNumber:Number;
  function get myNumber():Number {
    trace("getting");  // 確認用
    return _myNumber;
  }
  function set myNumber(n:Number):Void {
    trace("setting");  // 確認用
    _myNumber = n;
  }
}

// FLA(SWF)ファイル
// フレームアクション: テスト用
var obj:GetterSetterTest = new GetterSetterTest();
obj.myNumber = 1;

// 出力ウィンドウの結果
setting
getting

2. 原因
ActionScript 2.0の黙示的なget/setメソッドの定義は、ActionScript 1.0のObject.addProperty()メソッドの処理に相当します。しかし、Object.addProperty()メソッドで定義したプロパティに値を設定しても、get関数は呼出されません。

// フレームアクション
function GetterSetterTest() {
}
GetterSetterTest.prototype.getMyNumber = function() {
  trace("getting");
  return _myNumber;
};
GetterSetterTest.prototype.setMyNumber = function(n) {
  trace("setting");
  _myNumber = n;
};
GetterSetterTest.prototype.addProperty
  ("myNumber", GetterSetterTest.prototype.getMyNumber, GetterSetterTest.prototype.setMyNumber);

// テスト用
var obj = new GetterSetterTest();
obj.myNumber = 1;
// trace(obj.myNumber);  // コメントを外せばget関数が呼出されます

// 出力ウィンドウの結果
setting

ActionScript 2.0の黙示的なget/setメソッドも、SWFには基本的にObject.addProperty()と同じ処理内容(バイトコード)が書き出されます。ActionScript 2.0の黙示的なget/setメソッドの場合には、set関数の最後にget関数の戻り値が返されているものと考えられます。つまり、set関数で記述するなら、以下のような処理になっているものと推測されます。

// ActionScript 2.0の黙示的なsetメソッドと同値のset関数
GetterSetterTest.prototype.setMyNumber = function(n) {
  // trace("setting");  // 確認用
  _myNumber = n;
  return this.getMyNumber();  // get関数の戻り値を返す処理が追加
};

3. 対処法
get関数へのアクセスは、おそらく意図的に追加されたものでしょう。その意味では、実装と考えるべきかもしれません。しかし、この動作により不具合が発生する場合には、黙示的なget/setメソッドの使用そのものを再検討する必要があるでしょう[*1]。

 

[*1] 黙示的なsetメソッドに空のreturnステートメントを追加することで、getメソッドの呼出しそのものは回避することが可能です。get関数へのアクセスが、returnステートメントにより、阻止されるためです。

class GetterSetterTest {
  var _myNumber:Number;
  // [中略]
  function set myNumber(n:Number):Void {
    trace("setting");  // 確認用
    myNumber = n;
    return;  // get関数へのアクセスを回避
  }
}

// FLA(SWF)ファイル
// フレームアクション: テスト用
var obj:GetterSetterTest = new GetterSetterTest();
trace(obj.myNumber = 1);  // 出力: undefined

しかしこの場合、プロパティの代入式が、値を返さなくなってしまいます。かといって、returnステートメントには、戻り値を加えることができません。returnに戻り値を指定すると、コンパイルエラーになります。

_____

作成者: 野中文雄
作成日: 2004年2月28日


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