サイトトップ

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

Macromedia Flash非公式テクニカルノート

クラス定義にプライベートなクラスが複数あるとコンパイルできない

ID: FN0909001 Product: Flash Platform: All Version: CS4/ActionScript 3.0

問題
クラス定義に複数のプライベートなクラスを加えると、[コンパイルエラー]が起こってSWFファイルにパブリッシュ(コンパイル)できないことがあります。

「プライベートなクラス」というのは、ファイル名と同名のメインとなるクラスが記述されたpackageステートメントブロック({})の外に定義されたクラスです(Flash CS4 Professional[ヘルプ]の[ActionScript 3.0のプログラミング] > [ActionScript言語とシンタックス] > [パッケージと名前空間]の「パッケージの作成」の項参照)。他のActionScript(AS)ファイルのクラスからはアクセスできないため、このように呼ばれます[*1]

【プライベートなクラスの定義】
package {
  import flash.display.Sprite;
  public class クラス名 extends Sprite {
    public function クラス名() {
      // 処理の記述
    }
  }
}
class プライベートクラス名 {
  public function プライベートクラス名() {
    // 処理の記述
  }
}

問題は、以下のようなクラスPrivateClassIssueを定義してふたつのプライベートなクラスを加えると、つぎのように#1120の[コンパイルエラー]が発生することです(図001)。この現象は、Flash CS4 Professionalで報告されています。

1120: 未定義のプロパティ _str へのアクセスです。
package {
  import flash.display.Sprite;
  public class PrivateClassIssue extends Sprite {
    public function PrivateClassIssue() {
      var _str:String = "hello";   // ローカル変数にアクセス
    }
  }
}
// プライベートなクラスをふたつ定義
class PrivateClass_1 {}
class PrivateClass_2 {}

図001■Flash CS4 Professionalでふたつのプライベートクラスを定義した場合の[コンパイルエラー]
図001

[*1]「プライベートクラス」というのは一般的な呼び名で、Flashの[ヘルプ]その他のドキュメントにそのような用語は使われていません。実際、クラスにアクセス制御の属性としてprivateは指定できません(プライベートなクラスに指定できるのは、デフォルトのinternalのみです)。

プライベートなクラスは、ファイルを開けてみないと存在がわかりません。つまり、見通しのよさは失われます。その意味からは、できるだけひとつのファイルにひとつのクラスを定義することが望ましいでしょう(Flash CS3 Professional[ヘルプ]の[ActionScript 3.0のプログラミング] > [ActionScriptの使用について] > [カスタムクラスの作成] > [クラスの構成に関する提案]参照)。


原因
この[コンパイルエラー]#1120は、変数が宣言されていないことを意味します(図002)。つまり、ローカル変数のvar宣言がコンパイラに認識されていないようです。これまでのところ、Flash CS3 ProfessionalやFlex SDKでは、この問題は確認されていません。したがって、Flash CS4 Professionalのバグである可能性が高いと考えられます。

図002■Flash CS4 Professionalの[ヘルプ]に掲載された[コンパイルエラー]#1120
図002


対処法
この問題を避けるには、プライベートなクラスのいずれかにObject以外の何らかのスーパークラスをもたせます。たとえば、前掲のクラスPrivateClassIssueに定義したプライベートなクラスのひとつ(PrivateClass_1)にArrayクラスを継承させるだけで、[コンパイルエラー]は解消します。

// プライベートなクラスのひとつに他のクラスを継承させる
class PrivateClass_1 extends Array {}
class PrivateClass_2 {}

したがって、さしあたっての対症療法としては、空のダミーのクラスを定義し、プライベートなクラスのひとつにそれを継承させることが考えられます。つぎのスクリプト001は、前掲のクラスPrivateClassIssueに定義されたプライベートなクラスのひとつPrivateClass_1に、別に定義したら空のクラスDummyを継承させました。これで[コンパイルエラー]はなくなります(図003)。

スクリプト001■プライベートなクラスのひとつにダミーのクラスを継承させる
    // ActionScript 3.0クラス定義ファイル: PrivateClassIssue.as
  1. package {
  2.   import flash.display.Sprite;
  3.   public class PrivateClassIssue extends Sprite {
  4.     public function PrivateClassIssue() {
  5.       var _str:String = "hello";
  6.       trace(_str);   // 確認用
  7.     }
  8.   }
  9. }
  10. class PrivateClass_1 extends Dummy {}   // プライベートなクラスにダミーのクラスを継承させる
  11. class PrivateClass_2 {}
    // ActionScript 3.0クラス定義ファイル: Dummy.as
    // 空のダミーのクラスを別のActionScript(AS)ファイルとして定義
  1. package {
  2.   public class Dummy {}
  3. }

図003■[コンパイルエラー]なしにtrace()結果が[出力]パネルに表示される
図003

前掲[ヘルプ]の[コンパイルエラー]#1120の説明(図002)に示唆されているとおり、「未定義のプロパティ」というエラーを避けるためには、[パブリッシュ設定]の[ActionScript 3.0の詳細設定]([ファイル] > [パブリッシュ設定]の[Flash]タブで[スクリプト]の[ActionScript 3.0]が選択された右横の[設定]ボタンをクリック)で[Strictモード]をオフにする方法もあります(図004)。ただし、変数の未宣言その他の厳密なコンパイルチェックがされなくなります。そのため、筆者としてはあまりお勧めできません。

図004■[ActionScript 3.0の詳細設定]ダイアログボックスで[Strictモード]を解除
図004

作成者: 野中文雄
作成日: 2009年9月30日


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