ActionScript 3.0 には XML リテラルなるものがあり、ソースコード中にいきなり XML の定義が出来てしまう。
var employees:XML = <employees> <employee ssn="123-123-1234"> <name first="John" last="Doe"/> <address> <street>11 Main St.</street> <city>San Francisco</city> <state>CA</state> <zip>98765</zip> </address> </employee> <employee ssn="789-789-7890"> <name first="Mary" last="Roe"/> <address> <street>99 Broad St.</street> <city>Newton</city> <state>MA</state> <zip>01234</zip> </address> </employee> </employees>;
XML - ActionScript 3.0 言語およびコンポーネントリファレンス の例そのまんまだけども。なんつーかこう、スゲー柔軟だなぁと衝撃を受けました。
更に驚いたのが、ECMAScript for XML(E4X)なるものにも対応していること。こいつは何者かっていうと、こんな感じにラクに XML を扱えるようにしてくれるもの。
trace(employees.employee[0].address.zip); // 98765 trace(employees.employee[1].@ssn); // 789-789-7890
XML のノードには "."で、属性には "@" でアクセスができる。いやなんつーかこんなにお手軽に XML 扱えていいのか、ってぐらい驚きました。
でまぁ、これだけだと「ふーん」なんですが。Flex のライブラリに flash.utils.describeType() というものがあります。こいつは何者かというと、いわゆるリフレクション。ただ、結果を XML で返してくれるところがおもしろい。
試しにこんなコードを実行してみると、
var x:XML = flash.utils.describeType(String); trace(x.toXMLString());
こんな感じの結果が返ってくる。
<type name="String" base="Class" isDynamic="true" isFinal="true" isStatic="true"> <extendsClass type="Class"/> <extendsClass type="Object"/> <constant name="length" type="int"/> <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/> <factory type="String"> <extendsClass type="Object"/> <constructor> <parameter index="1" type="*" optional="true"/> </constructor> <accessor name="length" access="readonly" type="int" declaredBy="String"/> </factory> </type>
とまぁ、クラスの情報を色々と見ることができる。public なメソッドが見れて無いけど String は特別扱いなのかねぇ……
で、コレを上手いこと使ってやると面白いことができる。具体的には MXML と ActionScript の分離。画面デザインとロジックの分割テクニック | デベロッパーセンター で紹介されてる ViewHelper は describeType を使ってクラスの情報を取得して、イベントハンドラとイベントを命名規則で結び付けてます。いわゆる CoC ってヤツですな。
となると気になるのは yui-frameworks ですが、これもやっぱり同じことをやっていました。org.seasar.akabana.yui.core.reflection.ClassRef を覗いてみると、
public function ClassRef( clazz:Class ){ var describeTypeXml:XML = flash.utils.describeType(clazz); concreteClass = clazz; super( describeTypeXml ); assembleMetadataRef(describeTypeXml.factory[0]); assembleConstructor(describeTypeXml.factory[0]); assemblePropertyRef(describeTypeXml.factory[0]); assembleFunctionRef(describeTypeXml.factory[0]); assembleInterfaces(describeTypeXml.factory[0]); assemblePackage( describeTypeXml ); assembleThis( describeTypeXml ); }
こんな感じ。assemble* でクラス表現の XML の各要素を走査してクラスの情報を組み立ててました。
ActionScript は中々面白いですなー。