- 2009年10月30日 22:40
- ActionScript 3.0 | Ruby
日にちびちびとRubyを触ってます。そんな備忘録。 今回はAS3とRubyのクラス定義について見比べてみましょう。
クラス定義
ActionScript 3.0
まずはおなじみのAS3のクラス定義です。class定義キーワードを使って、TestClassを定義します。クラス定義にあたってのポイントを列挙します。
- ファイル名とクラス名は一致しなければならない。
- 定義範囲は{}で決定。
- パッケージ
- アクセス制御指定子を省略した場合は、クラス、インスタンス変数・メソッドは自動的にinternalとなる。コンストラクタはpublicに設定される。
- 変数にはvar宣言を付けなければならない。
- 変数・定数・引数・戻り値には型を付けることが推奨されている。
package {
class TestClass{
var name:String;
function TestClass(name:String):void {
this.name = name
}
function hello():String {
return "hello" + name;
}
}
}
TestClassクラスはいたって単純で、コンストラクタで引数としてnameプロパティを受け取り、helloメソッドを実行すると、コンストラクタで設定されたnameプロパティの値を、返します。
これをRubyで表現するといかのようになります。
Ruby
class TestClass
def initialize(name);
@name = name.to_s;#インスタンス変数
end
def hello()
"hello #{@name} !";
end
end
以下に相違点を列挙します。
- ファイル名とクラス名は一致しない。慣習としてクラス名TestClassの場合、ファイル名はtest_class.rbというような形式になる。
- 定義範囲は定義文-class endで決定。
- アクセス制御指定子を省略した場合は、クラス、メソッドは自動的にpublicとなる。
- インスタンス変数はそのままでは外部からアクセスできない
- initializeメソッドがコンストラクタ
- 暗黙型変換はされないのでto_メソッドを使って任意の型に変換しなければいけない
- 文字列内で#{}を使うことで、変数にアクセスしたり制御文を定義できる。
- インスタンス変数には@を付ける。特別な宣言分は必要なく、どこで定義してもインスタンス内から参照できる
- return文は省略でき、その場合は最終行の値を自動的に返す。
- 型指定はない
アクセス制御
外部からのアクセス方法について定義するアクセス制御指定子。ActionScript 3.0では、public,protected,internal,privateが存在しますが、パッケージが存在しないRubyはpublic,protected,privateの三つを使うことができます。前述で、メソッドのアクセス制御指定子は省略することができ、その場合はpublicに設定されると書きましたが注意が必要です。ActionScript 3.0では"対象のメソッドに対して付与する"イメージですが、Rubyは"実行時に制御を切り替える"イメージです。どういうことかというと、たとえば以下のような場合、メソッドaは、privateを付与されます。続くbメソッドでは、publicでなくprivateが付与されるわけです。つまり、制御指定子を宣言した時点で、制御指定子を省略した場合の挙動が変動します。続くメソッドcでは、再びアクセス制御指定子を使用してpublicに設定していますので、アクセス制御指定子が省略されたメソッドdはpublicが設定されます。
ActionScript 3.0
private function a():String{
return "a"
}
function b():String{//internalになる
return "a"
}
protected function c():String{
return "a"
}
Ruby
private
def a()
"a"
end
def b()//ここはprivate
"b"
end
public
def c()
"c"
end
def d()
"d"
end
アクセサ
Rubyでは、インスタンス変数に外部からアクセスすることはできません。ActionScript3.0でいう、privateに設定されている状態だと考えてください。外部からインスタンス変数を読み込んだり書き込んだりしたい場合、アクセサを使用することが義務づけられます。
ActionScript 3.0
ActionScript 3.0でのアクセサは、メソッドを介して行われます。privateに設定したインスタンス変数を参照および、書き込む専用のメソッドを、get/setキーワードをそれぞれ使用して定義します。読み込み専用の場合には、getのみを定義します。
private var _name:String;
public function get name():String { return _name; }
public function set name(value:String):void {
_name = value;
}
Ruby
Rubyにおけるアクセサの定義は、attr_accessorメソッドを使用します。一見キーワードに見えますが、Moduleクラスに定義されているメソッドです。ちなみにRubyではメソッドの実行に()を使っても使わなくても構いません。このattr_accessorに指定される引数は、インスタンス変数ですが、ここではシンボルという任意の文字列と一対一に対応するオブジェクトで指定します。この方法を使うと一行で済み、無駄がありません。読み込み専用の場合は、attr_readerを使用します。
class TestClass
attr_accessor :name;#nameをアクセサに
def initialize(name);
@name = name.to_s;#インスタンス変数
end
def hello()
"hello #{@name} !";
end
end
クラスの呼び出しと生成
Rubyのクラスの呼び出しは、ActionScriptとさして代わりありません。基本的には、読み込んで、呼び出して、生成です。
ActionScript 3.0
imoprt TestClass;
var test = new TestClass("tom");
tarce(test.hello());//hello tom !
test.name = "bob";
tarce(test.hello());//hello bob !
Ruby
#main.rb require "test_class.rb"; test = TestClass.new "tom"; p test.hello ;#"hello tom !" test.name = "bob"; p test.hello ;#"hello bob !"
importの代わりに、requireメソッドを使用します。Rubyの全てのクラスはObjectを継承しており、Objectはkernelモジュールをインクルードしています。このモジュールで定義されているのがrequireです。引数にはクラス名ではなく、ファイル名を与えます。そして、クラスの生成です。ActionScript 3.0の場合にはnew 演算子をクラスの前で使用しますが、Rubyではnewメソッドが継承されています。生成したオブジェクトはnewで与えられた引数を自動的にinitialize()メソッドに委譲して実行します。三行目で実行されている pは、ActionScript 3.0でいうtraceで、出力用のメソッドです。
まとめ
RubyとActionScript 3.0の定義方法、少しの違いはあれど、さして抵抗は無いと思えます。Perlの代わりにと、まつもとゆきひろ氏が開発した言語、Ruby。Rubyを学習することで、ところどころにちりばめられた効率化のための欠片を垣間見ることが出来るかも知れません。
次回は継承とクラスメソッドについてご紹介します。



