サイトトップ

Director Flash 書籍 業務内容 プロフィール

Flash OOP for ActionScript 3.0

第2章 ActionScript 2.0から3.0へのガイド
◎2-5 ふとした疑問と気になる機能

●2-5-1 クラスについてのふとした疑問
ActionScript 3.0でできるようになったと思えることや、2.0では実行していたことで、具体的にどうやったらよいか[ヘルプ]でもわかりにくかったり、見つけにくい処理があります。とくにクラス定義に関わる項目を、アトランダムにいくつかご紹介します。

2-5-1-1 クラスを文字列で参照したい
[ライブラリ]から複数のシンボルのインスタンスを、動的に作成したい場合があります。ActionScript 2.0では、それらのシンボルに連番の識別子を設定すれば、ループ処理でカウンタの数値と組合わせた文字列の識別子をMovieClip.attachMovie()メソッドに渡して、インスタンスを作成することができました。

ところが、ActionScript 3.0はシンボルに識別子を用いることができず、クラス名を設定して(図2-5-001)コンストラクタメソッドの呼出しによりインスタンスを生成しなければなりません。そこで、クラス名を文字列で参照して、コンストラクタを呼出す必要が生じます。

▲図2-5-001■[リンケージプロパティ]ダイアログには[クラス]を設定
Flash Player and AVM
△ActionScript 3.0では、[識別子]は入力できない。

文字列で指定されたクラス名からクラスの参照を得るには、flash.utils.getDefinitionByName()関数を用います。引数の文字列にクラス名を指定すれば、クラスの参照が返ります。クラスの参照を格納する変数には、Classでデータ型を指定します。

文字列"Pen"が代入された変数name_strを用いて、前記フレームアクションと同じようにインスタンスを作成するには、つぎのようなスクリプトを記述します(スクリプト2-5-001)。

▲スクリプト2-5-001■クラス名の文字列からインスタンスを作成する

// フレームアクション
var name_str:String = "Pen";
var myClass:Class = Class(getDefinitionByName(name_str));
var myInstance:MovieClip = new myClass();
addChild(myInstance);

△getDefinitionByName()関数の戻り値はObject型なので、データをClass型に変換する必要がある。

flash.utils.getDefinitionByName()関数の戻り値はObjectです。したがって、Class型の変数に代入するには、データ型を変換しなければなりません。そこで、データをClass型に変換するため、戻り値のオブジェクトをClass()の引数に指定しています。

[MEMO]2-5-001 キャスト
データ型を明示的に変換することは、一般に「キャスト」と呼ばれます。式の値を、あるクラスのデータ型にキャストするには、つぎのようなステートメントを記述します([ヘルプ]→[ActionScript 3.0のプログラミング]→[ActionScript言語とシンタックス]→[データ型]→[型変換]参照)。

クラス(式);

ほかにも、DisplayObject.rootプロパティの戻り値は、DisplayObjectインスタンスです。たとえば、このプロパティからメインタイムラインの参照が得られた場合、MovieClipクラスのプロパティやメソッドにアクセスしようとすれば、同じようにMovieClipクラスでキャストする必要があります(筆者サイトFumioNonaka.com「rootプロパティでメインタイムラインの関数にアクセスできない」<http://www.fumiononaka.com/TechNotes/Flash/FN0707001.html>参照)。

冒頭に採上げた複数のシンボルに連番のクラス名を設定した場合には、forステートメントのループ処理によって、それらのインスタンスを動的に作成することができます。3つのMovieClipシンボルにクラス名を、それぞれ"Pen0"、"Pen1"、"Pen2"と設定したとしましょう。フレームアクションは、つぎのようになります。

// フレームアクション
for (var i:int = 0; i<3; i++) {
  var name_str:String = "Pen"+i;
  var myClass:Class = Class(getDefinitionByName(name_str));
  var myInstance:MovieClip = new myClass();
  addChild(myInstance);
  // インスタンスの座標などを設定する処理
}

2-5-1-2 クラスを複数のMovieClipシンボルに設定したい
ActionScript 2.0では、ひとつのクラスを[ライブラリ]にある複数のMovieClipシンボルに適用することが可能でした。[リンケージプロパティ]ダイアログでシンボルを一意に指定するための[識別子]が、[クラス]とは別に入力できるからです(図2-5-002)。

▲図2-5-002■[リンケージプロパティ]ダイアログの[識別子]と[クラス]
Flash_OOP_2-5-001.gif
△[識別子]はユニークでなければならない。[クラス]には他のシンボルと同じクラス名が指定可能。

ところが、ActionScript 3.0で[リンケージプロパティ]ダイアログに設定する[クラス]は、識別子の役割も果たします(前掲図2-5-001参照)。つまり、クラス名は必ずユニークでなければなりません。したがって、ひとつのクラスを[リンケージプロパティ]ダイアログで複数のMovieClipシンボルの[クラス]に適用することはできない、ということになります。

しかし、MovieClipを継承したクラスをMovieClipシンボルに設定すると、MovieClipクラスのプロパティやメソッドはどのMovieClipシンボルのインスタンスも使うことができます。ですから、複数のMovieClipシンボルに適用したいクラスは、直接シンボルに設定するのでなく、そのクラスを継承したサブクラスをつくり、そのサブクラスをシンボルに設定すればよいのです。

もっとも、そのためだけに、空のサブクラスをいちいち定義するのは面倒です。[リンケージプロパティ]ダイアログには、[クラス]のほかに[基本クラス]というフィールドがあります(図2-5-003)。この[基本クラス]が、実は継承するスーパークラスの指定なのです。

▲図2-5-003■[リンケージプロパティ]ダイアログで継承するクラスを[基本クラス]に指定する
Flash_OOP_2-5-002.gif
△スーパークラスを示す[基本クラス]には、他のシンボルと同じクラス名が指定可能。[クラス]はユニークでなければならない。

[基本クラス]には、MovieClipシンボルの場合、デフォルトではflash.display.MovieClipが表示されます(前掲図2-5-001参照)。そこに、複数のMovieClipシンボルに設定したいクラスを入力すればよいのです(図2-5-003)。[基本クラス]のフィールドであれば、同じクラスを別のMovieClipシンボルに設定しても問題ありません。

なお、[クラス]にはユニークな名前を設定する必要があります。けれど、わざわざ空のクラスを定義しなくても、そのクラスが存在しなければFlashが自動的に生成します(図2-5-004)。ですから、識別子としてユニークな名前を入力するだけで構いません。

▲図2-5-004■クラスの自動生成を警告するダイアログ
Flash_OOP_2-3-010.gif
△クラス定義が見つからないと、Flashが自動的にその名前で空のクラスを生成する。

2-5-1-3 プライベートなクラス
クラスに対しては、private属性キーワードは指定できません。もっとも、ActionScript 3.0には、ひとつのファイルにひとつのクラスしか定義できないという制限がなくなりました。つまり、「1つの.asファイルに複数のクラスのソースコードを保存できます」([ヘルプ]→[ActionScript 3.0のプログラミング]→[ActionScriptの使用について]→[カスタムクラスの作成]→[クラスの構成に関する提案]参照)。

すると、ファイル名と同じ名前をつけたメインのクラスに加えて、そのファイルに定義したクラスは、メイン以外のクラスからはアクセスする手段がありません。したがって、その追加したクラスは、プライベートなクラスといってよい位置づけになります。そこで本稿では、「プライベートなクラス」と呼ぶことにします。

プライベートなクラスは、つぎのようにpackageステートメントブロックの外に定義します。

// ActionScript 3.0クラス定義ファイル: クラス名.as
package [パッケージ名] {
  public class クラス名 {
    function クラス名() {   // コンストラクタ
      // 初期化処理
    }
  }
}
// packageの外に定義
class プライベートクラス名 {
  function プライベートクラス名() {   // コンストラクタ
  }
}

クラス定義(AS)ファイルの中に別のクラスが加わっていることは、そのファイルを開けて見るまではわかりません。その意味では、プライベートなクラスは、その存在や構成が把握しにくいものになります。メインのクラスとのみ、密接な関係をもって使われるクラスに、限定して利用すべきでしょう。

[MEMO]2-5-002 プライベートなクラスの利用
[ヘルプ]は、「1つのソースファイルに複数のクラスを保存する」ことは、つぎのふたつの理由で推奨しないとしています([ActionScript 3.0のプログラミング]→[ActionScriptの使用について]→[カスタムクラスの作成]→[クラスの構成に関する提案])。

  • 「複数のクラスが1つの大きなファイルに保存されている場合、個々のクラスを再利用するのが困難になります。」
  • 「ファイル名とクラス名が対応していない場合、特定のクラスのソースコードを見つけるのが困難です。」

したがって「Adobeでは、クラスひとつひとつのソースコードは、つねにそれぞれのクラスのファイルに、クラスと同じ名前で保存することを推奨します」と述べます([ヘルプ]の原文となる英語版ドキュメント<http://livedocs.adobe.com/flash/9.0/main/00000034.html>より筆者訳。日本語版[ヘルプ]が「個人用のファイル」と邦訳しているのは、「個別のファイル」の誤りでしょう)。

もっとも、第1の理由については、メインのクラスと切離して再利用される可能性のあるクラスが、プライベートに定義されることはあまりないように思われます。

[*筆者用参考] akihiro kamijo「package」、JavaA2Z「内部クラス」、同「privateクラス」。

プライベートなクラスには、ひとつ確認されている問題があります。クラス(static)プロパティの初期値にブライベートクラスのインスタンスを代入しようとすると、ランタイムエラーが発生します(図2-5-005)。

そのテスト用のクラスは、以下のスクリプト2-5-002のとおりです。クラスをテストするには、クラス定義(AS)ファイルと同階層に保存したFlashムービー(FLA)ファイルのフレームアクションから、クラスPrivateClassTestのコンストラクタを呼出します。

// Flashムービー(FLA)ファイル
// フレームアクション
var obj:PrivateClassTest = new PrivateClassTest();
▲スクリプト2-5-002■クラスプロパティの初期値にプライベートクラスのインスタンスを設定

// ActionScript 3.0クラス定義ファイル: PrivateClassTest.as
package {
  public class PrivateClassTest {
    // trace(PrivateClass); // 確認用
    static private var privateObject:PrivateClass = new PrivateClass();
    public function PrivateClassTest() {}
  }
}
// プライベートクラス
class PrivateClass {
  public function PrivateClass() {}
}

△呼出したPrivateClassが「コンストラクタではありません」というランタイムエラーになる。

クラスPrivateClassTestのクラス(static)プロパティとしてprivateObjectを宣言し、初期値としてプライベートなクラスPrivateClassのコンストラクタを呼出して、そのインスタンスを代入しています。すると、呼出したPrivateClassが「コンストラクタではありません」というランタイムエラーになります(図2-5-005)。

▲図2-5-005■クラスプロパティの初期化時にプライベートクラスのコンストラクタを呼出せない
Flash_OOP_2-5-004.gif
△プライベートクラスのコンストラクタが認識されていない。

[MEMO]2-5-003 クラスプロパティの初期値にプライベートクラスのインスタンスが設定できない理由
クラス(static)プロパティは、クラスのロード時に1度初期化されます。その初期値を得るために他のクラスにアクセスしている場合には、そのアクセス先のクラスも初期化され、値が返されます。

ところが、プライベートクラスは、メインのクラスプロパティでアクセスしていても、初期化がメインクラスの後に行われるようです。そのため、クラスプロパティで参照したとき、プライベートクラスが初期化されておらず、nullが返されてしまうため、メンバー(プロパティやメソッド)が存在しないものとして扱われてしまうのです。

なお、上記スクリプト2-5-002でクラスプロパティを宣言する前の、コメントアウトされているtrace()関数のステートメントを有効にすれば、クラスPrivateClassへの参照がnullで返されることを確認できます。

2-5-1-4 プライベートなコンストラクタ
2-3-2-2「ActionScript 3.0と2.0の違い」でご説明したとおり、ActionScript 3.0では2.0と異なり、コンストラクタメソッドにはpublic属性しか指定できません。コンストラクタがクラス外から呼ばれないように、private属性を指定することはできないということです。

しかし、実際上privateなコンストラクタメソッドを定義したい場合はありえます。ひとつは、Mathクラスのように、クラス(static)メンバー(プロパティ・定数、メソッド)のみで構成され、インスタンスを作成する必要がない場合です。もうひとつが、インスタンスをひとつだけしか生成しない「Singletonパターン」と呼ばれるデザインです。

[MEMO]2-5-003 Singletonパターン
Javaなどの言語で解説されているソフトウェア開発の「デザインパターン」という類型の中に、「Singleton」と呼ばれるパターンがあります。Singletonパターンでは、クラスからインスタンスはひとつしか作成できません。インスタンスを作成・取得する専用のクラス(static)メソッドを用意し、クラスの外からはコンストラクタが呼出せない設計にします。

ActionScriptに実装されているSingletonパターンに近いクラスには、SharedObjectがあります。SharedObjectクラスはコンストラクタを使わず、クラス(static)メソッドSharedObject.getLocal()によりインスタンスを作成・取得します。なお、SharedObject.getLocal()メソッドに渡す引数が異なると、新たなインスタンスを作成するという仕様になっています。

ActionScript 2.0では、コンストタラクタ関数にprivate属性が指定できたので、クラス外から呼出されないようにすることは簡単でした(Javaも、コンストラクタにprivate修飾子を指定して、Singletonパターンを実装しています)。ActionScript 3.0では、残念ながらこの指定ができません。そこで以下のサンプル(スクリプト2-5-003)では、コンストラクタの呼出しが内部からであることを示すフラグにより、クラス外からの呼出しを回避する手法を採っています。

クラス内部からの呼出しであることを示すフラグは、静的(static)プロパティとして設定しました。コンストラクタは、そのプロパティが内部呼出しを示さないときは、エラーを生成(throw)します。インスタンスを取得・生成する静的メソッドは、メソッド内からコンストラクタメソッドを呼出す前に、そのプロパティを内部呼出しの値に設定すればよいでしょう。

▲スクリプト2-5-003■Singletonパターンを実装したクラス

package {
  import flash.errors.IllegalOperationError;
  public class Singleton {
    private static var instance:Singleton = null;   // インスタンスを格納する
    private static var internallyCalled:Boolean = false;   // 内部呼出しかどうかを示すフラグ
    // コンストラクタメソッド
    public function Singleton() {
      if (internallyCalled) {   // フラグが内部呼出しを示せば
        // 本来の処理を行う
        trace("constructor is called");   // テスト用
        internallyCalled = false;   // 内部呼出しのフラグを初期値に戻す
      } else {   // フラグが内部呼出しを示さなければ
        // エラーをthrow
        throw new IllegalOperationError ("Use Singleton.getInstance() to get the instance");
      }
    }
    // Singletonクラスのインスタンスを返す
    public static function getInstance():Singleton {
      if(Singleton.instance == null) {   // インスタンスが未生成なら
        trace("instance is being created");   // テスト用
        internallyCalled = true;   // 内部呼出しのフラグを設定
        instance = new Singleton();   // コンストラクタメソッドを呼出す
      }
      return instance;   // 格納されたインスタンスを返す
    }
  }
}

△コンストラクタの呼出しが内部からであることを示すフラグにより、クラス外からの呼出しを回避。

上記スクリプト2-5-003のSingletonクラスは、以下のようなフレームアクション(スクリプト2-5-004)で簡単にテストすることができます。実行すると、[Output]パネルにはつぎのような出力が表示されます。

instance is being created
constructor is called
true

▲スクリプト2-5-004■クラスSingletonをテストするフレームアクション

// Flashムービー(FLA)ファイル
// フレームアクション
var mySingleton0:Singleton = Singleton.getInstance();
var mySingleton1:Singleton = Singleton.getInstance();
// var mySingleton2:Singleton = new Singleton();   // エラー
trace(mySingleton0 == mySingleton1);

△getInstance()メソッドを2度呼出しても、返されるインスタンスは同じ。

まず、ステートメントの第1行目では、コンストラクタメソッドの呼出しが行われ、コンストラクタは正常にインスタンスを生成して返します。つぎに、ステートメントの第2行目は、新規のインスタンスは生成せず、すでに1行目で生成されたインスタンスを返します。したがって、最後の行のステートメントで、ふたつのインスタンスは同一であることが示されます。

コメントアウトされた第3行目を有効にすると、コンストラクタを外部から呼出すため、ランタイムエラーが発生します(図2-5-006)。

▲図2-5-006■Singletonパターンは外部からコンストラクタを呼出せない
Flash_OOP_2-5-005.gif
△コンストラクタを呼出すとランタイムエラーが発生する。

[MEMO]2-5-004 Singletonパターンの他の実装方法
privateなコンストラクタの実装は、ほかにも考えられるでしょう。たとえば、Adobeのエンジニアのブログakihiro kamijo「コンストラクタ(とSingleton)」(<http://weblogs.macromedia.com/akamijo/archives/2005/12/interface.cfm>)では、プライベートなクラスをコンストラクタの引数に指定することで、外部から呼出しができないようにしています。


●2-5-2 気になる新機能
ActionScript 3.0の新機能は、細かいものまで採上げたらきりがありません。紙幅の関係もありますので、スクリプティングの観点から、あまり詳しい解説を要せず、知っておくと便利という機能を3つだけご紹介します。

2-5-2-1 E4X(ECMAScript for XML)
「E4X」はECMAScript for XMLの略で、ECMAScript 3を拡張して、XMLのネイティブデータを扱うための仕様です。「ECMAScript for XML (E4X) Specification」として第2版が公開されています(<http://www.ecma-international.org/publications/standards/Ecma-357.htm>)。ActionScript 3.0では、このE4Xに対応しました。ActionScript 2.0/1.0と比べて、XMLデータの扱いは格段に楽になります。

まず、XMLデータは直接タグを使って(<>)リテラル記述できます。ActionScript 2.0のように、文字列からXMLデータに変換する必要がありません。

var cs3:XML = <cs3>
  <product suite="Web">
    <name>Flash</name>
    <price>699</price>
  </product>
  <product suite="Web">
    <name>Dreamweaver</name>
    <price>399</price>
  </product>
  <product suite="Design">
    <name>Photoshop</name>
    <price>649</price>
  </product>
  <product suite="Design">
    <name>Illustrator</name>
    <price>599</price>
  </product>
</cs3>

[MEMO]2-5-005 リテラル
「リテラル」とは、プログラム(のソースコード)に直接記載される値を示します。変数から値を取出したり、関数(メソッド)の戻り値を受取るのではなく、文字列(String型)や数値(Number/int/uint型)を直接記述する場合がその典型です。

たとえば、つぎの代入式の右辺値は、いずれもリテラルです。

var product_str:String = "Flash CS3 Professional";
var nPlayerVersion:int = 9;

値をリテラルで記述できるデータの例としては、このほか論理(ブーリアン)値(Boolean型)や配列(Array型)、XML(XML型)、Object(Object型)などが挙げられます(なお、[ヘルプ]→[ActionScript 3.0のプログラミング]→[ActionScript言語とシンタックス]→[シンタックス]の「リテラル」の項参照)。

[*筆者用参考] e-Words「リテラル

XMLのノードは、ActionScript 2.0のようにひとつひとつ取出して調べるのでなく、ドット演算子(.)で名前を指定して取得することができます。取出した子ノード群は、XMLListインスタンスになります。

var products:XMLList = cs3.product;
trace(products);

// 出力:
<product suite="Web">
  <name>Flash</name>
  <price>699</price>
</product>
<product suite="Web">
  <name>Dreamweaver</name>
  <price>399</price>
</product>
<product suite="Design">
  <name>Photoshop</name>
  <price>649</price>
</product>
<product suite="Design">
  <name>Illustrator</name>
  <price>599</price>
</product>

さらに、取出す子ノードを指定して、絞り込むことも可能です。

trace(products.name);

// 出力:
<name>Flash</name>
<name>Dreamweaver</name>
<name>Photoshop</name>
<name>Illustrator</name>

括弧()を使って、要素名を条件として指定することもできます。

trace(products.(name == "Flash"));

// 出力:
<product suite="Web">
  <name>Flash</name>
  <price>699</price>
</product>

また、属性は@を用いて指定します。

trace(products.(@suite == "Web"));

// 出力:
<product suite="Web">
  <name>Flash</name>
  <price>699</price>
</product>
<product suite="Web">
  <name>Dreamweaver</name>
  <price>399</price>
</product>

○2-5-2-2 正規表現(RegExpクラス)
RegExpクラスは、正規表現を処理します。「正規表現」(Regular Expression)とは、文字列のパターンを表現する記述です。RegExpインスタンスで指定したパターンを使って文字列を調べたり、Stringクラスのメソッドに引数として指定することにより文字列を操作することもできます。

RegExpインスタンスはRegExpクラスのコンストラクタを呼出して生成できるほか、以下のようにパターンをスラッシュ(/)で括ってリテラル記述することも可能です。リテラル記述の方が簡単で見やすいでしょう。

var 変数:RegExp = /パターン/

たとえば、"AS"という文字列をパターンとするRegExpインスタンスは、スラッシュで括って/AS/と記述して作成します。RegExp.test()メソッドを使うと、引数に指定した文字列にパターンが含まれるかどうかが調べられます。

var my_str:String = "Flashファイル(AS 3.0)";
var myPattern:RegExp = /AS/;
var myResult:Boolean = myPattern.test(my_str);
trace(myResult);   // 出力: true

RegExpインスタンスのパターンは、Stringクラスのメソッドにも引数として指定できるものがあります。String.replace()メソッドの第1引数にRegExpインスタンスを渡すと、そのパターンに当てはまる文字列を第2引数の文字列と置換えます。

以下のスクリプトは、復帰文字"\r"を改行として用いた文字列に対して、String.replace()メソッドを用いて、"\r"を"<br>に置換えます。String.replace()メソッドメソッドの第1引数には、RegExpインスタンス/\r/をパターンとして渡しています。

var my_str:String = "Flash\rDreamweaver\rPhotoshop\rIllustrator";
var myPattern:RegExp = /\r/;
var result_str:String = my_str.replace(myPattern, "<br>");
trace(result_str);

// 出力:
Flash<br>Dreamweaver
Photoshop
Illustrator

上記スクリプトで渡したRegExpインスタンスでは、パターンに当てはまる最初の文字列のみを示す表現になります。したがって、String.replace()メソッドの置換結果も、最初の改行("\r")のみが文字列"<br>に変わっています。パターンと一致する文字列すべてを指定したいときには、正規表現にg(global)フラグを添えます。

以下のスクリプトでは、正規表現にgフラグを加えましたので、String.replace()メソッドが参照する文字列中のすべての改行("\r")は、文字列"<br>"に置き換わります。

var myPattern:RegExp = /\r/g;   // gフラグを加える
var result_str:String = my_str.replace(myPattern, "<br>");
trace(result_str);   // 出力: Flash<br>Dreamweaver<br>Photoshop<br>Illustrator

選択制御文字|を使うと、複数のパターンのいずれかひとつを対象とする指定ができます。

たとえば、テキストファイルの改行コードは、プラットフォームによって異なります。Windowsは復帰文字+改行文字("\r\n")、Macintoshが復帰文字("\r")、UNIXやLinuxは改行文字("\n")です。これらいずれのファイルの文字列であっても同じ改行コード、たとえば復帰文字("\r")に統一するためには、その文字列に対してString.replace()メソッドを、つぎのような正規表現の引数で呼出します。

var my_str:String = "Flash\nDreamweaver\r\nPhotoshop\rIllustrator";
var myPattern:RegExp = /\n|\r\n/g;
var result_str:String = my_str.replace(myPattern, "\r");
trace(result_str.split("\r"));   // 出力: Flash,Dreamweaver,Photoshop,Illustrator

[出力]パネルでは制御コード自体は表示されず、改行そのものになるため、改行コードが意図どおりに変更されたかどうかは確かめられません。そこで上記スクリプトでは、統一されるべき復帰文字("\r")を区切り文字として変更後の文字列にString.split()メソッドを適用しています。配列エレメントが改行位置で分けられ、余分な改行が表れないことにより、正しく変更されたことが確認できます。

CSV(カンマ区切り)ファイルを扱う場合など、テキストデータを最終的にエレメントに分けて配列に収めたい場合には、String.split()メソッドの区切り文字にも正規表現が使えます。

var myPattern:RegExp = /\n|\r\n|\r/g;
var result_array:Array = my_str.split(myPattern);
trace(result_array);   // 出力: Flash,Dreamweaver,Photoshop,Illustrator

正規表現には、特別な役割をもつ「メタ文字」や複数の文字を表す「メタシーケンス」などの特殊な文字があり、文字列の複雑なパターンが指定できます。たとえば、つぎのスクリプトは正規表現でメールアドレスのパターンを指定し、String.match()メソッドによりそのパターンに当てはまる文字列を配列に抜出します。

var my_str:String = "email:fumio@fumiononaka.com";
var myPattern:RegExp = /[\w.-]+@[\w.-]+\.[\w.-]+/g;
var result_array:Array = my_str.match(myPattern);
trace(result_array[0]);   // 出力: fumio@fumiononaka.com

上記スクリプトの正規表現で用いられた特殊な文字は、下表2-5-001のとおりです。まず、[\w.-]は半角英数字または_(アンダースコア)、もしくは.(ドット)あるいは-(ハイフン)のうちのひと文字(以下「半角英数字等」と表記します)を表します。つぎに、+(プラス)は、その前に記述された半角英数字等が、ひと文字以上繰返す文字列を意味します。\.は、.(ドット)が特殊な文字ですので、それがエスケープされて普通の文字の.(ドット)を指します。

したがって、上記の正規表現で示されるメールアドレスのパターンは、半角英数字等の1文字以上の文字列の後に@が続き、その後にさらに半角英数字等の1文字以上の文字列、そして.(ドット)が必要で、最後にまた半角英数字等の1文字以上の文字列があるという指定になります。

▲表2-5-001■正規表現で用いられる特殊な文字の一部
特殊な文字 説明
\ エスケープ文字です。メタ文字などの特殊な文字を、普通の文字として指定したいとき、その文字の前に記述します。
+ 直前の文字のパターンを1回以上繰返す指定です。
[] 文字クラスを定義します。文字クラスは、ひとつの文字が取り得る文字パターンのリストを指定します。文字クラス内では、メタ文字のエスケープは不要です。
\w 半角英数字(A〜Z、a〜z、0〜9)または_(アンダースコア)ひと文字の指定です。

なお、メタ文字やメタシーケンスなどの特殊な文字について詳しくは、[ヘルプ]→[ActionScript 3.0のプログラミング]→[正規表現の使用]→[正規表現のシンタックス]→[文字、メタ文字、およびメタシーケンス]をお読みください。

[MEMO]2-5-006 正規表現によるメールアドレスの判別
前掲スクリプトのメールアドレスの判別は、ごく簡易なものです。実際のメールアドレスには、\や!、/、!、%などの文字も使用できるようです。したがって、正確な判別には、メールアドレスの仕様を確認したうえで、かなり込入った指定が必要になります。

興味のある方は、ネットで「正規表現 メールアドレス」をキーワードに検索すると、詳しい情報が得られるでしょう。

[*筆者用参考] akihiro kamijo「正規表現」、phpspot「正規表現:メールアドレスかどうか調べる」、正規表現のサンプル集「メールアドレスを検索する」、Webプログラマー+WebデザイナーなZARU日記「メールアドレスを正規表現で判定する方法

○2-5-2-3 ドキュメントクラス
ActionScript 2.0では、[ライブラリ]のMovieClipシンボルにクラス指定することはできました。しかし、メインタイムラインにはクラスが設定できません。ActionScript 3.0の「ドキュメントクラス」は、メインタイムラインにクラスを適用します。プロパティインスペクタの[ドキュメントクラス]フィールドにクラス名を入力して設定します(図2-5-007)。

▲図2-5-007■プロパティインスペクタの[ドキュメントクラス]にクラス名を設定
Flash_OOP_2-5-006.gif
△[ドキュメントクラス]は、メインタイムラインに設定される。

[ドキュメントクラス]はタイムラインに関連づけるクラスですので、定義の仕方はMovieClipシンボルに設定する クラスと基本的に同じです(2-3-4-1「MovieClipシンボルに設定するActionScript 3.0クラス」参照)。つまり、クラスにはpublic属性を指定し、またMovieClipクラスを継承する必要があります。クラス名は、もちろん任意です。

[MEMO]2-5-007[ドキュメントクラス]の継承するクラス
[ドキュメントクラス]に設定するクラスは、Spriteクラスを継承しても一応は動作します。しかしそうすると、複数フレームは使えず、フレームにスクリプトが一切書けません。したがって、通常はMovieClipクラスを継承すべきでしょう。

[ドキュメントクラス]を利用すると、Flashムービー(FLA)ファイルそのものには一切のスクリプトを記述しなくて済むことになります。

[Prev/Main]


作成者: 野中文雄
作成日: 2008年2月13日


Copyright © 2001-2008 Fumio Nonaka.  All rights reserved.