トップへ戻るニュースフォーラムFLASH-ML 過去ログBak@Flaダウンロードよくある質問と答
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
メイン
   コーダーズルーム【スクリプト系】
     [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
eShin
Åê¹ÆNo.4219
投稿日時: 2004-2-25 21:42
半人前
居住地:
投稿: 32
使用環境:
XP Pro(SP1)+IE6
MX2004 Pro
[AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
AS2で暗黙的な取得 / 設定メソッドを使用しています。
プロパティにsetしただけなのに、getメソッドも実行されてしまいます。

原因が分かる方、よろしくお願い致します。
#何かものすごく単純な間違いをしている気がします。。。


---------------
クラスにsetメソッドとgetメソッドを下記のように書きました。

class Test1 {
 private var pX:String = "";
  
 function get x():String {
  trace("get:"+pX);
  return pX;
 }
  
 function set x(newX:String):Void {
  pX = newX;
  trace("set:"+pX);
  //return;
 }
  
 function Test1() {
  trace("start!");
 }
}


そして、フレームスクリプトに下記のように書きました。
_root.onLoad = function() {
	myTest1 = new Test1();
	myTest1.x = "hoge";
}


これで実行すると、下記のようにトレースされます。
getメソッドも実行されているようです。。
start!
set:hoge
get:hoge  ←★なぜこれが表示されるのか。。?


ただ、setメソッドの最後にreturnすると、"get:hoge"は表示されません。


----------------

youich
Åê¹ÆNo.4228
投稿日時: 2004-2-26 0:17
職人
居住地: kobe
投稿: 349
使用環境:
Tiger
Re: [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
引用:

eShinさんは書きました:
AS2で暗黙的な取得 / 設定メソッドを使用しています。
プロパティにsetしただけなのに、getメソッドも実行されてしまいます。

原因が分かる方、よろしくお願い致します。
#何かものすごく単純な間違いをしている気がします。。。


---------------
クラスにsetメソッドとgetメソッドを下記のように書きました。

class Test1 {
 private var pX:String = "";
  
 function get x():String {
  trace("get:"+pX);
  return pX;
 }
  
 function set x(newX:String):Void {
  pX = newX;
  trace("set:"+pX);
  //return;
 }
  
 function Test1() {
  trace("start!");
 }
}


そして、フレームスクリプトに下記のように書きました。
_root.onLoad = function() {
	myTest1 = new Test1();
	myTest1.x = "hoge";
}


これで実行すると、下記のようにトレースされます。
getメソッドも実行されているようです。。
start!
set:hoge
get:hoge  ←★なぜこれが表示されるのか。。?


ただ、setメソッドの最後にreturnすると、"get:hoge"は表示されません。



setterの中ではxの値を返す(リターンする)ようなコードにコンパイラが勝手にやってるんだと思います。
だからその時にgetterが呼ばれるということになるんじゃないかと思います。

で、何故こうするかというと、

var myTest1:Test1 = new Test1();
var dummy = myTest1.x = "hoge";

と書けるようにする為だと思われます。。。思いますバッカリです。


----------------
- yo

加藤達雄
Åê¹ÆNo.4233
投稿日時: 2004-2-26 1:21
新米
居住地: 東京
投稿: 24
使用環境:
Win XP Pro
MX Pro 2004
Re: [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
こんばんは。
getが思わぬところで呼ばれてしまうことによる弊害の良い例がちょっと思いつきませんが、問題になる場合がありそうな気はします。

youichさんが言われるように、'='が連なったときのことが考慮されているのでしょうか。
ちなみに他のOOP言語では、Flashと違い、自然に期待する結果が得られるようです。

JScript .NETの例
class Class1
{
	private var pX:String = "";
	public function get x():String
	{
		print("get : " + pX);
		return pX.Substring(0, 2);
	}
	
	public function set x(value:String)
	{
		print("set : " + value);
		pX = value;
	}
	
}

var inst:Class1 = new Class1();
var str:String = inst.x = "hoge";
print(str);
print(inst.x);

/*出力
set : hoge
hoge
get : hoge
ho
*/


C#での例
using System;

namespace get_set_test
{
	class Class1
	{
		private string pX = "";
		public string x
		{
			get
			{
				Console.WriteLine("get : " + pX);
				return pX.Substring(0, 2);
			}
			set
			{
				Console.WriteLine("set : " + value);
				pX = value;
			}
		}

		[STAThread]
		static void Main(string[] args)
		{
			Class1 inst = new Class1();
			string str = inst.x = "hoge";
			Console.WriteLine(str);
			Console.WriteLine(inst.x);
		}
	}
}
/*
set : hoge
hoge
get : hoge
ho
*/

JScript .NETやC#では、'='が連なったときには、getが呼ばれないようになっているようです。
野中文雄
Åê¹ÆNo.4236
投稿日時: 2004-2-26 2:13
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
何となく、嫌な感じはしますね。
引用:
TatsuoKatoさんは書きました:
getが思わぬところで呼ばれてしまうことによる弊害の良い例がちょっと思いつきませんが、問題になる場合がありそうな気はします。

おそらく、そういうことのようです。
引用:
youichさんが言われるように、'='が連なったときのことが考慮されているのでしょうか。

Object.addProperty()メソッドでは、getterは呼ばれません。
// フレームアクション
function SetterGetterTest() {
}
SetterGetterTest.prototype.getUser = function() {
        trace("getting");
        return this.userName;
};
SetterGetterTest.prototype.setUser = function(name) {
        trace("setting");
        this.userName = name;
};
SetterGetterTest.prototype.addProperty("user",
SetterGetterTest.prototype.getUser, SetterGetterTest.prototype.setUser);
obj = new SetterGetterTest();
obj.user = "Jack";

// [出力]パネルの結果
setting

しかし、暗黙的なgetメソッドを設定すれば、戻り値の制御が可能になります。
// ActionScript 2.0クラス定義: SetterGetterTest.as
class SetterGetterTest {
        var userName:String;
        function get user():String {
                trace("getting");
                return "fixed";  // userName;
        }
        function set user(name:String):Void {
                trace("setting");
                userName = name;
                // return;
        }
}

// SWF: テスト用
// Frame action
var obj:SetterGetterTest = new SetterGetterTest();
trace(obj.user = "Jack");

// In the Output panel
setting
getting
fixed

これはObject.addProperty()メソッドではできないようです。つまり、この動作は実装と考えるべきなのでしょう。


----------------
 

youich
Åê¹ÆNo.4237
投稿日時: 2004-2-26 2:42
職人
居住地: kobe
投稿: 349
使用環境:
Tiger
Re: [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
引用:


何となく、嫌な感じはしますね。

setterで値を返す所まではいいと思いますけど (。。。と言いましたが、やはり必要性が感じられません)
それをgetterで返してるところがあかんと思います。
例えば


class MyTest{
	private var _value:Number;
	
	function get value(){
		return _value + 10;
	}
	
	function set value(v:Number){
		_value = v;
	}
}

で、MyTestクラスをつかうクライアントのほうは

var m:MyTest = new MyTest();
var n = m.value = 100;

trace(n); //110

この場合MyTestを使うほうにしてみれば、直感に反する、意図しない結果に
なるので、まずいと思いますね。

引用:

これはObject.addProperty()メソッドではできないようです。つまり、この動作は実装と考えるべきなのでしょう。

addPropertyといいますか、けっきょくMyTest.prototype.addProperty?
というコードにコンパイルされるのですが、その際setterにリターン文を追加しているので、
コンパイラの実装といえますでしょうか。


----------------
- yo

加藤達雄
Åê¹ÆNo.4240
投稿日時: 2004-2-26 4:18
新米
居住地: 東京
投稿: 24
使用環境:
Win XP Pro
MX Pro 2004
Re: [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
もう少し検証してみたのですが、このバグ(どうやらバグと言えそうです)はちょっと根が深いかもしれません。

最後のyouichさんの例で、

> var m:MyTest = new MyTest();



var m = new MyTest();

に変更すると、

var n = m.value = 100;
trace(n); //100
trace(m.value); //110

となります。つまり、このように型指定されていない場合のみ、期待する動作になります。
ちなみにこの場合、set時にgetも呼ばれますが(getファンクション内にtraceを入れておくと出力される)、setファンクション自体が返す値は、渡された引数そのままです。
型指定した場合には、setファンクションが返す値はgetファンクションの戻り値になってしまっています。

これはマクロメディアに報告したほうが良さそうですね。私からも報告しますが、報告件数は多いほど良いので皆さんもお願いします。
eShin
Åê¹ÆNo.4263
投稿日時: 2004-2-26 15:42
半人前
居住地:
投稿: 32
使用環境:
XP Pro(SP1)+IE6
MX2004 Pro
Re: [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
youichさん、加藤さん、野中さん、いつもありがとうございます。

私ももう少し検証してみました。

最後のyouichさんの例で、setの最後にreturn;を入れると、

var n = m.value = 100;
trace(n); //undefined
trace(m.value); //110

になります。期待した動作とは違いますが、return;を入れたためにsetが
戻り値を返さないと考えると納得はできます。
また、set時にgetは呼ばれませんでした。(getにtraceを入れて確認しました。)

------------
次のトライです。
setの最後にreturn;を入れた上で、
> var m:MyTest = new MyTest();

var m = new MyTest();
に変更すると、

var n = m.value = 100;
trace(n); //100
trace(m.value); //110

になりました。期待した動作で、set時にgetも呼ばれませんでした。

------------
となると、当面の回避策としては、

・インスタンスを作成するときに、クラスの型指定をしない。
 var m = new MyTest();
・setの最後にreturn;を入れる

ですね。。

かなり気持ち悪いですがやむを得ないですね。
みなさんありがとうございました。

#今回は大ボケをしていなくて良かった。。
#Macromediaにも報告しておきます。


----------------

野中文雄
Åê¹ÆNo.4350
投稿日時: 2004-2-28 19:35
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
いっそ、黙示的なget/setメソッドを使わないという選択肢に、かなり傾きかけています。(^^;

[黙示的なsetメソッドの代入式でgetメソッドが呼出される]
引用:
eShinさんは書きました:
となると、当面の回避策としては、

・インスタンスを作成するときに、クラスの型指定をしない。
 var m = new MyTest();
・setの最後にreturn;を入れる

ですね。。


----------------
 

eShin
Åê¹ÆNo.4368
投稿日時: 2004-2-29 18:16
半人前
居住地:
投稿: 32
使用環境:
XP Pro(SP1)+IE6
MX2004 Pro
Re: [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
野中さん、こんにちは。

私自身は、せっかくスマートに書ける機能だから使おうかな、という選択肢に傾いています。(^^;

代入式の戻り値を利用する書き方はしませんし、クラスの型指定もしたいので、
setの最後にreturn;を入れることを忘れなければよいかな、と。

#「非公式テクニカルノート」いつも参考にさせていただいています。なので、ちょっとうれしいです。


----------------

takiguchi
Åê¹ÆNo.4497
投稿日時: 2004-3-3 17:06
半人前
居住地: 東京
投稿: 38
使用環境:
Win2K,FlashMX2004Pro7.0.1
Re: [AS2]暗黙的な取得 / 設定メソッドでsetするとgetメソッドも実行されてしまう。。
こんにちわ。
途中から失礼します。eShinさん、貴重な情報ありがとうございます。
私はAS2.0を使用するのが怖くなってきちゃいました…(^^;;

コンポーネントの作成に関して、色々と調べてたところ
海外サイトで以下のような報告がされてました。
Inspectable Getters and Setters and Live Preview
私も再現してみたのですが同様の結果が得られています。
また、暗黙的なsetterでgetterが呼び出される他に、ライブプレビューではさらに奇妙な振る舞いをするようです。
パラメータを[Inspectable]なプロパティにバインドするためか?、初期化(construct)前に
全てのsetterとgetterが呼ばれるようです。
[Inspectable]なプロパティへアクセスする時に、通常は暗黙的なsetter,getterを使用すると思うのですが、
このような奇妙な現象が起こると、暗黙的なsetter,getterを使用することにかなりの抵抗を感じてしまいますけど…
UIコンポーネントのsetterでは、内部データをsetする他にinvalidate()の呼び出しを行ったりしますので、
暗黙的なsetter,getterを使わないで対処する他の方法が考えつきません。
[Inspectable]なプロパティをpublicプロパティだけにバインドするのも無理がありそうですし、
setter,getterを"暗黙的にしない"というのもバインドするのが無理っぽいですし…

Inspectable Getters and Setters and Live Previewで議論されている内容ですが、
私にはかなり難しくて、おまけに英語も苦手なので、確認を兼ねて恥ずかしながら要約を記述したいと思います。
重要な内容だと思うのですが、公式ドキュメント等が出されることはないのかなぁ?やっぱり…

他の掲示板の引用をこちらで取り上げるのは不謹慎かと思いますので、
問題がある場合は早急に削除します。
(^^;;

まず報告されている方は、「プロパティを更新した(setter呼び出し)時に通常は、
再描画(更新したプロパティに依存する関数の呼び出し)などを合わせて行うけど、
初期化(construct)前はそのようなことをしたくないので、初期化(construct)完了を知らせる__initedフラグを使って
setter呼び出し時における再描画の場合分けをすると良いのではないか」と提案していると思います。

返答されているRob氏は、UIコンポーネント(UIObject or/and UIComponent の継承)に偏った回答を
されていて、対処方法としてはsetterで直接draw()を呼ぶのではなくて、
invalidate()を呼び出せば良いとの提案をされていると思います。
理由として、1フレームでinvalidate()が何回呼び出されても結局次のフレーム間隔1/(f[fps])で
draw()が呼ばれるだけで、実際の処理はそこで行われるからであるというようなことを述べていると思います。
また、createChildren()メソッドの呼び出しを知らせるchildrenCreatedフラグの紹介をし、自身は
_endInit()メソッド(hook extentionって?)に相当する独自のinitComplete()メソッドを
追加することで対処するとも述べています。

これに対して、報告されている方は、UIObject.invalidate()に相当する独自のinvalidateは作ったけど
UIコンポーネントに限らず一般的な例を取り上げてるつもりで、さらには、
setterでinvalidateの呼び出しが必須であるとは言えないと述べていると思います。
そして、setterでredrawの必要がない一例として、
urlプロパティをsetしてからコンテンツのロードを行う場合などが紹介されています。
そして、次にこのことの対処方法が紹介されいて

・draw()内にloadコマンドを置く
・doLater(load)を使ってonLoadイベントハンドラ内でdraw/invalidateを呼び出す

doLaterはonEnterFrameを利用して文字通りフレーム間隔1/(f[fps])分遅らせて関数を呼ぶような
メソッドであると思うのですが…?難しくてよく分からないっす…

…と、こまごまとした内容になってます。
暗黙的なsetterでgetterが呼ばれるという話の内容から、脱線しちゃって申し訳ないです。
ただ…
コンポーネントを作成するに当たって、[Inspectable]である暗黙的なsetter,getterに
パラメータをバインドすることで生じる弊害って、何か考えられますでしょうか?


あと、既存のコンポーネントのクラスファイルを読んでると、

function set prop(p){…;}, function setProp(p){…;}
function get prop(){…;}, function getProp(){…;}

のようなパターンで、あるプロパティのsetter,getterが2つ用意されていることが多いですよね。
そして、さらに

function set prop(p){setProp(p);}, function setProp(p){__prop=p;}
function get prop(){return getProp();}, function getProp(){return __prop;}

のようなパターンもいくつかみられます。
どちらにしても暗黙的なsetterでgetterが呼ばれてしまうみたいなのですが、
どのような意図でこのようなことをしているのか?ちょっと気になります。
もしかして、本件に関係することかもしれないと思ったのですが…私の思い違いっぽいですね。

それから…
この件に関してMMさんに報告してから何かレスポンスはありましたでしょうか?
私は報告してないのですが、支障がなければMMさんからのコメントを公開していただけるとありがたいです。
(1) 2 »
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 
Copyright (C) 2003 FLASH-japan. All rights reserved.
Powered by Xoops