Studying AS3 namespace

先日行われた FxUG@関西の勉強会で、AS3 namespace についての発表を行った際の資料です。カスタム namespace の基本的な使い方は理解しておくといろんな場面で活用できると思います。みんなもっと namespace まくろう!!!

namespace

  • 基本的な namespace
  • as3 namespace
  • カスタム namespace
  • namespace 応用と実践
  • namespace を利用したライブラリ

基本的な namespace

  • public
  • private
  • protected
  • internal

ご存じの通り、基本的な namespace

  • 上三つは、Java とほぼ同じ

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]();

利用場面 : 例

インスタンスの特定挙動の記述

namespace を効率よく利用

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

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 を使おう!