In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: カスタムクラスのプロパティーを再帰的に列挙する方法

======================================
カスタムクラスのプロパティーを列挙する方法
Object型だと型指定できないのでカスタムクラスを
作りたいときはよくあると思います。

ただ、カスタムクラスはfor inで走査できず不便。
カスタムクラスにtoObject()というメソッドを
追加してプロパティーを列挙できるようにしました。

他にも良い方法がありましたら教えてー
====================================== 
超ムリヤリ・・・
/**
 * Copyright meat18 ( http://wonderfl.net/user/meat18 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/oy21
 */

// forked from clockmaker's カスタムクラスのプロパティーを再帰的に列挙する方法
/* ======================================
   カスタムクラスのプロパティーを列挙する方法
   Object型だと型指定できないのでカスタムクラスを
   作りたいときはよくあると思います。

   ただ、カスタムクラスはfor inで走査できず不便。
   カスタムクラスにtoObject()というメソッドを
   追加してプロパティーを列挙できるようにしました。

   他にも良い方法がありましたら教えてー
 ====================================== */
/*

超ムリヤリ・・・

*/
package
{
	import com.bit101.components.Label;
	import com.bit101.components.Text;
	import flash.display.Sprite;
	import jp.nium.utils.ObjectUtil;
	import flash.utils.describeType;
	
	[SWF(backgroundColor=0xCCCCCC)]
	public class Main extends Sprite{
		public function Main(){
			// 県
			var pref_1:Pref = new Pref();
			pref_1.prefName = "TOKYO";
			pref_1.id = 13;
			
			var pref_2:Pref = new Pref();
			pref_2.prefName = "OSAKA";
			pref_2.id = 27;
			
			// 人
			var person_1:Persion = new Persion();
			person_1.name = "YASU";
			person_1.age = 27;
			person_1.pref = pref_1;
			
			var person_2:Persion = new Persion();
			person_2.name = "NOBU";
			person_2.age = 29;
			person_2.pref = pref_2;
			
			// 格納
			var arr:Array = [ person_1, person_2];
			
			// 出力パターン1 (for inで出力)
			// カスタムクラスのプロパティーは列挙されない
			new Label(this, 10, 50, "for..in");
			new Text(this, 10, 70, ObjectUtil.toString(arr));
			
			// 出力パターン2 (getPropertyという自作メソッドを利用)
			// カスタムクラスのプロパティーを列挙できる
			var out:Array = [];
			for (var i:int = 0; i < arr.length; i++){
				out.push(getProperty(arr[i]));
			}
			new Label(this, 10, 190, "for..in with toObject()");
			new Text(this, 10, 210, ObjectUtil.toString(out));
			
			// タイトル
			var l:Label = new Label(this, 10, 10, "FOR IN PROPERTY OF CUSTOM CLASS");
			l.scaleX = l.scaleY = 2;
		}
		
		private function getProperty(o:*):Object{
			var obj:Object = {};
			//describeType(o)で、オブジェクトoに関する情報をXMLで出力。
			//カスタムプロパティ、インスタンス変数の情報はdescribeType(o).variableに格納されています。
			if((describeType(o).variable.@name).length() > 0){
				for(var k:int = 0; k < (describeType(o).variable.@name).length(); k ++){
					var prp:String = String(describeType(o).variable.@name[k]);
					obj[prp] = ((describeType(o[prp]).variable.@name).length() != 0 || (describeType(o[prp]).accessor.@name).length() != 0) && !(o[prp] is String)?getProperty(o[prp]):o[prp];
				}
			}
			//同じように、ビルトインのプロパティはdescribeType(o).accessorに格納されています。
			//かなり力技感の漂うコードです・・・。
			//ちなみにaccessorがvariableを持つことはない(と勝手に思い込んでいる)ので、コードが前半と少し異なります。
			if((describeType(o).accessor.@name).length() > 0){
				for(k = 0; k < (describeType(o).accessor.@name).length() - 1; k ++){
					prp = String(describeType(o).accessor.@name[k]);
					obj[prp] = (describeType(o[prp]).accessor.@name).length() != 0 && !(o[prp] is String)?getProperty(o[prp]):o[prp];
				}
			}
			return obj;
		}
    }
}

// 都道府県 試しにMovieClipクラスを継承させてみる
//正しく動作すると、MovieClipから継承されたプロパティも一緒に列挙されます。
import flash.display.*;
class Pref extends MovieClip
{
    public function Pref(initObject:Object = null)
    {
        if (initObject)
        {
            this.id = initObject.id;
            this.prefName = initObject.prefName;
        }
    }

    public var id:int; //JISコード
    public var prefName:String; //都道府県名

    public function toObject():Object
    {
        return {
            prefName: prefName,
            id: id
        };
    }
}

// 人
class Persion
{
    public function Persion(initObject:Object = null)
    {
        if (initObject)
        {
            this.age = initObject.age;
            this.name = initObject.name;
            this.pref = new Pref(initObject.pref);
        }
    }

    public var age:int; // 年齢
    public var name:String; // 人名
    public var pref:Pref; // 所属する都道府県

    public function toObject():Object
    {
        return {
            name: name,
            age: age,
            pref: pref.toObject()
        };
    }
}