Pebble Coding

ソフトウェアエンジニアによるIT技術、数学の備忘録

C++,Objective-C の使い手のためのRuby講座

Rubyのクラスの理解に苦しんでおります。
Rubyのこの概念はC++,Objective-C でいうところのコレだよって感じに
強引に理解していこうと思います。
RubyはわりとObjective-Cに似ているので、そこから理解した方が
早く理解できそうです。
なぜかRubyの本にはObjective-Cとのアナロジーはまったく出てこないのですが。

1) Rubyのオブジェクトは全てBasicObjectを継承している。(Ruby1.9以降)
Objective-Cでいうところの
全てのオブジェクトはNSObjectを継承している。
と同じです。

2) Rubyでは変数は、スクリプト実行時に型が決まる。
C++でいうところの、変数宣言が全て型テンプレートに近いですかね。

3) 継承元クラス(Human)に存在するメソッドと同じ名前のメソッド
継承先クラス(Male)で定義し、Maleクラスでその名前のメソッド
コールした場合は、継承先クラス(Male)のメソッドのみが呼ばれる。
つまり、overrideされる。
継承元のメソッドをコールしたい場合はsuperが使える。
C++Objective-Cと同じです。

4) クラス名(とモジュール名)の先頭は大文字以外指定不可能。
ちなみにクラス名の先頭を小文字にすると、以下のようなエラーメッセージが出て、実行時エラーになる。
class/module name must be CONSTANT

5) 変数名の先頭を大文字にすると定数と認識し、以後、その変数は再設定できない。
C++で自動的に変数の前にconstが付くとでも覚えるか。

6) メソッド内で小文字から始まる変数を初めて使ったら、その変数のスコープはメソッド内。
C++Objective-Cと同じです。

7) メソッド内で@小文字から始まる変数を初めて使ったら、その変数のスコープはクラス内。
これはC++Objective-Cにはない概念。
宣言しなくても使えちゃうスクリプト言語特有動作。
次のように使うと@valにはnilが入っている。

~$ cat a.rb
class A
def bad
p @val
end
end
a = A.new
a.bad
~$ ruby a.rb
nil

通常は、クラスにdef initializeを定義してその中で
インスタンス変数は全て初期化するのがお行儀がいいスタイル。
それにしても初期化メソッドの名前がObjective-Cのinitよりも長いというのはなんとなく違和感。
initでいいんじゃねって気がする。

8) シンボルはRuby全空間で同じ名前なら、同じオブジェクトを指す。
Rubyが勝手にインクリメントして値を割り当ててくれる#defineのようなもの。
シンボル名の先頭は大文字小文字どちらも許容される。

9) 全てのメソッドは戻り値を持つ
最後に評価した式が戻り値として使用される。
途中でメソッドから抜けたい場合は、returnを使うことができる。
Rubyではreturnをなるべく書かないのが慣習のようだ。

10)既存の組み込みクラスに対してメソッドを追加することができる。
Objective-Cでいうところの、カテゴリ機能そのものです。

11)メタプログラミング(Rubyでは黒魔術という呼び名がついています。)が可能である。
Objective-Cメタプログラミングと同じです。
例えば、メソッド名を文字列で与えてそれを実行するなど。

12)moduleは2つの機能がある。
一つはC++でいうnamespace、もう一つはMixIn。
MixInはRuby独特なので覚えるしかない。

13)nilオブジェクトは条件式でfalseと判定される。
Objective-Cと同じです。

※余談
Ruby on Railsメタプログラミング使いまくりです。
Railsの難しさはRubyメタプログラミング機能があることを知らないで
入ってしまうことにあるとやっと理解した。
Objective-Cメタプログラミング機能があることも
多分あまり知られてはいないだろう。