Studying AS3 namespace
先日行われた FxUG@関西の勉強会で、AS3 namespace についての発表を行った際の資料です。カスタム namespace の基本的な使い方は理解しておくといろんな場面で活用できると思います。みんなもっと namespace まくろう!!!
namespace
- 基本的な namespace
- as3 namespace
- カスタム namespace
- namespace 応用と実践
- namespace を利用したライブラリ
internal namespace
デフォルト namespace
宣言無しで書くと、internal となる
function myFunction():void { }
internal は、同一パッケージからのみ、呼び出し可能
internal namespace の使いどころ
あまりない…です…。
- パッケージ間のみで使われる、ユーティリティメソッドの定義など
その他あったら教えて欲しい
AS3 namespace
AS3 の深い部分で、AS3 namespace が使われている
- ES では prototype が使われる
- AS3 の(標準では)クラスベースのプロパティ継承
これらの問題の解決に。
コアクラスを例に見てみよう
Array#join() の実装って?
// こんな感じ? Array.prototype.join = function():String {};
// それともこんな? class Array { public function join():String {};
tarmarin の Array#join() の実装
// AS3 namespace! AS3 function join(sep=void 0):String { return _join(this, sep) } prototype.join = function(sep=void 0):String { return _join(this, sep) }
tarmarin の Array#join() の実装
- AS3 namespace, prototye, 両方で実装
- これにより、prototype/クラスベースどちらにも対応可能
- コンパイラオプションにより、挙動を変えられる
- -as3 = true, -es = false (デフォルト)
var a:Array = [1,2,3]; a.AS3::join == a.join; // true
カスタム namespace
namespace は独自に定義できるよ
public namespace myNamespace = 'http://example.com/mynamespace'; myNamespace function myFunction():void {};
カスタム namespace の呼び出し
namespace::propetyName で呼び出せる
myNamespace::myFunction();
var methodName:String = 'myFunction'; instance.myNamespace::[methodName]();
カスタム namespace の利用例
- flash.utils.Proxy
import flash.utils.Proxy; import flash.utils.flash_proxy; dynamic class MyProxy extends Proxy { override flash_proxy function callProperty(methodName:*, ... args):* {
- 特別なメソッドを、別の名前空間に
- コンフリクトを防ぐ
カスタム namespace の利用例
- mx.core.mx_internal
Flex では、mx_internal 名前空間で、Flex フレームワークからのみの呼び出しに制限している
- けど、時々どうしても弄りたいときがある
import mx.core.mx_internal; public class MyButton extends Button { override mx_internal function getCurrentIconName():String { // あとはお好きに...
namespace 応用と実践
実際にどんなケースでカスタム namespace を使う?
namespace とリフレクション
特定名前空間のメソッドを取得可能
// instance の myNamespace な メソッドを全部取得 var res:XMLList = describeType(instance).method.(String(attribute('uri')) == myNamespace.uri); var methods:Array = []; for each (var n:* in res) methods.push(n.@name.toString());
myNamespace::myFunction(); var methodName:String = 'myFunction'; instance.myNamespace::[varName]();
利用場面 : 例
インスタンスの特定挙動の記述
- http://rails2u.com/misc/swf/Dot3d.swf
- http://rails2u.com/misc/swf/Dot3d.as
- motion namespace で、オブジェクトの動きを記述
namespace を効率よく利用
- describeType は重いので、XML をキャッシュ
- リフレクション用ライブラリ、AS3Reflect を使う
namespace を利用したライブラリ
他にもあると思いますが…
- AS3Unit
- KeyTypeListener
- Uffy
AS3Unit
http://www.libspark.org/wiki/yossy/AS3Unit
- Spark Project の yossy さん作
- test/before/after などの namespace を利用
test function foo():void {}; test function bar():void {}; before function setup():void {}; after function teardown():void {};
KeyTypeListener
http://d.hatena.ne.jp/secondlife/20070428/1177686633
- 利用しまくり(個人的に)
- 簡単なキーボード操作のユーティリティ
- key_down / key_up などの namespace を利用
key_down function j(): {}; // j キーが押されたら
Uffy
- http://github.com/hotchpotch/uffy/tree/master
- http://d.hatena.ne.jp/secondlife/20080719/p1
- javascript namespace を利用
- 定義したメソッドを、簡単に ExternalInterface 経由で呼び出せるように
import uffy.javascript; public class URI { javascript function getURL(...) javascript function postURL(...)
import uffy.Uffy; Uffy.register('URI', URI);
JS側からは…
var uffy = new Uffy('GetURL.swf'); uffy.load('URI', function(URI) { var uri = new URI; uri.getURL(url, function(result) { // ... }); });
まとめ
- namespace オモシロイヨー
- 便利なライブラリも作れます
- 自作フレームワークで多様すると便利そう
- みんなもっと namespace を使おう!