# 第1章 Ruby言語ミニマム

Ruby言語について、当面第一部を理解するのに必要な知識だけ簡単に解説して おく。プログラミング上のテクニックであるとか注意すべきところなんてもの は全く指摘しないので、この章を読んだからと言ってRubyプログラムが書ける ようになるわけではない。既にRuby言語の経験がある読者はこの章は飛ばし て問題ないだろう。

また文法については第二部で嫌というほど話すから、この章ではできるだけ文 法の詳細には関らないようにする。ハッシュリテラルなどバリエーションがあ る表記は最も多用されるもののみ示す。省略可能なものは原則的に省略せずに 示す。そのほうが構文規則がシンプルになるからだ。いちいち「省略できる」 とも言わない。

## オブジェクト

### 文字列

Rubyプログラムが操作できるものは全てオブジェクトである。Javaの`int`や `long`のような「基本型（primitive）」はない。例えば以下のように書くと それは「`content`」 という内容を持った文字列オブジェクト（`String`オブジェクト）である。

    "content"

単に文字列オブジェクトと言ったが、正確に言えばこれは文字列オブジェクト を生成する「式」である。だから、何回も書けばそのたびに別の文字列オブジェ クトが生成される。

    "content"
    "content"
    "content"

ここでは「`content`」という内容を持った文字列オブジェクトが三つ生成される。

ところで、オブジェクトがそこにあるだけではプログラマには見え ない。オブジェクトを端末に表示する方法を教えておこう。

    p("content")   # "content"と表示される

「`#`」以降はコメントだ。今後、結果はコメントとして付けておくことに する。

「`p(`……`)`」は関数`p`の呼び出しである。任意のオブジェクトを「そ れっぽく」表示してくれる。基本的にデバッグ用の関数だ。

厳密に言うとRubyには関数はないのだが、いまは関数と考えておいてよい。関 数はどこにいても使うことができる。

### 様々なリテラル

さて、直接オブジェクトを生成する式（リテラル）をもう少し説明しておこう。 まずは一般的なところで、整数と小数だ。

    # 整数
    1
    2
    100
    9999999999999999999999999   # どんなに大きな数でも使える

    # 小数
    1.0
    99.999
    1.3e4     # 1.3×10^4

これも全てオブジェクトを生成する式であることを忘れないでほしい。 繰り返すが、Rubyには「基本型」はない。

以下の表現は配列オブジェクトを生成する。

    [1, 2, 3]

このプログラムは整数1 2 3の三つをその順番で要素として持つ配列を生成す る。配列の要素には任意のオブジェクトが使えるので、こんなこともできる。

    [1, "string", 2, ["nested", "array"]]

さらに、以下の表現はハッシュテーブルを生成する。

    {"key"=>"value", "key2"=>"value2", "key3"=>"value3"}

ハッシュテーブルというのは、任意のオブジェクト同士の一対一対応を表す構 造だ。上記のように書くと次のような関係を記憶したテーブルができる。

    "key"   →  "value"
    "key2"  →  "value2"
    "key3"  →  "value3"

こうやって作ったハッシュテーブルオブジェクトに「`"key"`に対応付けられて るのは何？」と聞けば、「`"value"`だよ」と教えてもらえる。どうやって聞 くか。それにはメソッドを使う。

### メソッド呼び出し

オブジェクトに対してはメソッドが呼べる。C++用語ではメンバ関数である。 メソッドとは何か、という説明は必要ないと思うので記法だけ簡単に解説す る。

    "content".upcase()

ここでは文字列オブジェクト（内容は「content」）に対して`upcase`メソッド を呼び出している。`upcase`はアルファベットの小文字を大文字にした新しい文 字列を返すメソッドなので、次のような結果になる。

    p("content".upcase())   # "CONTENT"と表示される

メソッド呼び出しは連鎖してよい。

    "content".upcase().downcase()

この場合、`"content".upcase()`の返り値のオブジェクトに対して`downcase`メソッ ドを呼ぶ、ということになる。

またJavaやC++のような公開フィールド（メンバ変数）はない。オブジェクト のインターフェイスはメソッドのみである。

## プログラム

### トップレベル

Rubyでは式をいきなり書けばそれがプログラムになる。 C++やJavaのように`main()`を定義する必要はない。

    p("content")

これだけで完結したRubyプログラムである。このリストを`first.rb`という ファイルに入れたとすると、コマンドラインから次のように実行できる。

    % ruby first.rb
    "content"

`ruby`コマンドの`-e`オプションを使えばいちいちファイルを作る必要すらない。

    % ruby -e 'p("content")'
    "content"

ところで、`p`が書いてある場所はプログラムのネストレベルが一番低い、 つまりプログラム的には一番「上」なので、「トップレベル」と呼ばれている。 トップレベルがあるのはRubyのスクリプト言語としての大きな特徴だ。

Rubyは基本的に一行が一文である。終端のセミコロンなどは必要ない。 だから以下のプログラムは三文と解釈される。

    p("content")
    p("content".upcase())
    p("CONTENT".downcase())

実行すればこうなる。

    % ruby second.rb
    "content"
    "CONTENT"
    "content"

### ローカル変数

Rubyでは変数や定数は全てオブジェクトへの参照（`reference`）を 保持している。だから別の変数に代入しただけでコピーが起こったりはしない。 Javaならオブジェクト型変数、C++ならオブジェクトへのポインタを考えれば いいだろう。ただしそのポインタ自体の値は変更できない。

Rubyでは変数名の一文字目で変数の種別（スコープ）がわかるようになってい る。アルファベット小文字かアンダーバーで始まるのがローカル変数だ。そし て「`=`」を使って代入を書ける。

    str = "content"
    arr = [1,2,3]

最初の代入が変数宣言を兼ねるので宣言は必要ない。また変数には 型がないのでどんなオブジェクトだろうと無差別に代入できる。 以下のプログラムは全く合法である。

    lvar = "content"
    lvar = [1,2,3]
    lvar = 1

もっとも、やれるからと言ってやる必要はない。いろいろな種類のオブジェク トを一つの変数にごっちゃに入れたりすれば普通は読みにくくなるものだ。現 実にあるRubyプログラムなら、こういうことは滅多にしない。これはあくまで 例のための例である。

変数参照もごく常識的な記法だ。

    str = "content"
    p(str)           # "content"が表示される

それから変数がリファレンスを保持するという点を例で見ておこう。

    a = "content"
    b = a
    c = b

このプログラムを実行したあと、`a b c`三つのローカル変数が指しているのは 同じオブジェクトで、一行目の`"content"`で生成した文字列オブジェクトであ る図1。

図1: Rubyの変数はオブジェクトへの参照を保持する

ところで、ローカルと言うからにはどこかに対してローカルでなければならな いはずだが、しばらく後にならないとこの範囲を言うことができない。とりあ えずトップレベルは一つの「ローカル」スコープだ、ということだけ言ってお こう。

### 定数

変数名が大文字で始まるのが定数である。定数と言うからには（最初の）一回 しか代入できないものだ。

    Const = "content"
    PI = 3.1415926535

    p(Const)   # "content"と表示される

二回代入するとエラーになる。と言いたいのだが、実は警告だけでエラーにな らない。これは、Rubyプログラム自体を操作するアプリケーション、例えば 開発環境などで、同じファイルを二回ロードしたときにエラーにならないよう にするためだ。つまり実用のためにやむを得ず認めているだけで、本当はエラー にしたいのである。実際にもバージョン1.1まではエラーになっていた。

    C = 1
    C = 2   # 現実には警告が出るだけだが、理念としてはエラー

さて、定数という言葉で騙される人が多いのだが、定数というのは「いったん 指すオブジェクトを記憶したら二度と変えない」という意味である。定数の指 すオブジェクトそれ自体が変わらないわけではない。英語で言うなら、 constantよりもread onlyのほうがよりよく意図を示しているだろう （図2）。 ちなみにオブジェクト自体が変化しないよう指示するには`freeze`という 別の方法を使う。

図2: 定数はread onlyの意味

そして実は定数のスコープについてもまだ話せない。次の節でクラスとからめて 話すことにする。

### 制御構造

Rubyは制御構造が豊富で並べるだけでも大変なので、 とりあえず`if`と`while`はある、ということだけ言っておく。

    if i < 10 then
      # 本体
    end

    while i < 10 do
      # 本体
    end

条件式では`false`と`nil`という二つのオブジェクトだけが偽で、 残りのあらゆるオブジェクトは真になる。0や空文字列ももちろん真だ。

それとついでに、`false`だけでは収まりが悪いから`true`もある。 これも当然真だ。

## クラスとメソッド

### クラス

本来オブジェクト指向システムにおいてメソッドとはオブジェクトに所属する ものだ。だがそれはあくまで理想の世界でのこと。普通のプログラムなら同じ メソッドの集合を持つオブジェクトがたくさんあるわけで、もしバカ正直にオブ ジェクト単位で呼び出せるメソッドを記憶していたりしたら大変なことになっ てしまう。そこで普通はクラスとかマルチメソッドのような仕組みを利用し て定義の重複をなくすわけだ。

Rubyでは、オブジェクトとメソッドを結びつける仕組みとして伝統的な「クラス」 の概念を採用している。即ち全てのオブジェクトはただ一つのクラスに所属 しており、呼び出せるメソッドをクラスで決める。このときオブジェクトのこ とを「○○クラスのインスタンス（instance）」と言うのだった。

例えば文字列`"str"`は`String`クラスのインスタンスである。そしてその `String`クラスには`upcase`、`downcase`、`strip`、その他いろいろなメソッド が定義されているので、あたかも全ての文字列オブジェクトがこれらのメソッドに 反応できるかのように見えるわけだ。

    # みんなStringクラスに属するので同じメソッドが定義されている
           "content".upcase()
    "This is a pen.".upcase()
        "chapter II".upcase()

           "content".length()
    "This is a pen.".length()
        "chapter II".length()

ところで、呼び出したメソッドが定義されていなかったらどうなるのだろう。 静的な言語ならコンパイルエラーになるところだが、Rubyでは実行時例外にな る。実際に試してみよう。この程度の長さなら`-e`でプログラムを渡してしま うのが便利だ。

    % ruby -e '"str".bad_method()'
    -e:1: undefined method `bad_method' for "str":String (NoMethodError)

メソッドが見付からないときは`NoMethodError`というエラーになるようだ。

それと最後に、いちいち「`String`の`upcase`メソッド」などと言うのは煩わ しいので専用の記法を用意しておこう。「`String#upcase`」で「`String`ク ラスに定義された`upcase`メソッド」を示すことにする。

ちなみに「`String.upcase`」と書くとRubyの世界では全く別の意味を持つ。 それはどんな意味か。それは次の項で説明する。

### クラス定義

ここまでは既に定義されているクラスの話だった。 独自のクラスももちろん定義できる。 クラスを定義するには`class`文を使う。

    class C
    end

これは新しいクラス`C`の定義だ。定義したら次のように使うことができる。

    class C
    end
    c = C.new()   # クラスCのインスタンスを作成し変数cに代入

インスタンスを作成する記法は`new C`ではないので注意。うーん、なんだか `C.new()`という記法はメソッド呼び出しみたいだな、と思った読者は鋭い。 Rubyではオブジェクトを生成する式は単なるメソッド呼び出しなのである。

まずRubyにおいてクラス名とは定数名と同義である。ではクラス名と同名の定数 には何が入っているのか。実は、クラスが入っている。Rubyではプログラムが さわれるものは全てオブジェクトだったから、クラスも当然オブジェクトとし て表現されている。これをクラスオブジェクトと呼んでおこう。全てのクラス オブジェクトは`Class`クラスのインスタンスである。

つまり`class`文とは、新しいクラスオブジェクトを作り、クラス名と同名の定 数にそれを代入する、という操作である。一方インスタンスの生成とは、定数 を参照し、そのオブジェクトに対してメソッド（普通は`new`）を呼ぶ、という 操作である。以下のような例を見ると、インスタンスの生成が普通のメソッド 呼び出しとなんら変わらないことがよくわかるだろう。

    S = "content"
    class C
    end

    S.upcase()  # 定数Sの指すオブジェクトを得てメソッドupcaseを呼び出す
    C.new()     # 定数Cの指すオブジェクトを得てメソッドnewを呼び出す

そんなわけでRubyでは`new`は予約語ではない。

それから、作りたてのクラスのインスタンスでも`p`できるということを書いて おこう。

    class C
    end

    c = C.new()
    p(c)       # #<C:0x2acbd7e4>

さすがに文字列や整数のようにきれいに表示することはできないが、所属クラ スと内部IDを表示してくれる。ちなみにこのIDはオブジェクトを指すポインタ の値だったりする。

そうそう、すっかり忘れていたがメソッド名の記法についてだ。「`Object.new`」 はクラスオブジェクト`Object`それ自体に対して呼ぶメソッド`new`、の意味にな る。「`Object#new`」と「`Object.new`」は全く別物なので厳密に区別しなければ いけない。

    obj = Object.new()   # Object.new
    obj.new()            # Object#new

現実には`Object#new`なんてメソッドは定義されていないので このプログラムは二行目でエラーになる。あくまで表記の例として 受け取ってほしい。

### メソッド定義

クラスが定義できてもメソッドが定義できなかったら意味がない。 我々のクラス`C`にもメソッドを定義してみよう。

    class C
      def myupcase( str )
        return str.upcase()
      end
    end

メソッドを定義するには`def`文を使う。この例では`myupcase`という メソッドを定義した。パラメータは一つで名前は`str`である。 変数のときと同じく、パラメータ変数や返り値の型を書く必要はない。 またパラメータの数はいくつでもよい。

定義したメソッドを使ってみる。メソッドはデフォルトで外から呼べる ようになっている。

    c = C.new()
    result = c.myupcase("content")
    p(result)   # "CONTENT"が表示される

もちろん慣れればいちいち代入する必要はない。以下のように書いても同じで ある。

    p(C.new().myupcase("content"))   # 同じく"CONTENT"が表示される

### `self`

メソッド実行中は常に自分自身（メソッドが呼び出されたインスタンス）が 誰であるかという情報が保存されており、`self`でその情報を取ることができる。 C++やJavaで言えば`this`だ。確かめてみよう。

    class C
      def get_self()
        return self
      end
    end

    c = C.new()
    p(c)              # #<C:0x4026b438>
    p(c.get_self())   # #<C:0x4026b438>

見てのとおり、二つの式は全く同一のオブジェクトを返している。 つまり`c`に対するメソッド呼び出しの中にいるときには`self`は`c`であることが 確認できた。

では自分自身に対してメソッドを呼ぶにはどうしたらいいだろうか。 まず`self`経由で呼ぶ方法が考えられる。

    class C
      def my_p( obj )
        self.real_my_p(obj)   # 自分自身に対してメソッドを呼ぶ
      end

      def real_my_p( obj )
        p(obj)
      end
    end

    C.new().my_p(1)   # 1を表示

しかし自分自身のメソッドを呼ぶのに「自分の」とわざわざ指定しなければな らないのは面倒だ。それで`self`に対する呼び出しのときはメソッドを呼び出す 対象のオブジェクト（レシーバreceiver）を省略できるようになっている。

    class C
      def my_p( obj )
        real_my_p(obj)   # レシーバ指定なしで呼べる
      end

      def real_my_p( obj )
        p(obj)
      end
    end

    C.new().my_p(1)   # 1を表示

### インスタンス変数

オブジェクトはデータ + コードだ、という表現もあるくらいで、メソッドが定 義できるだけではあまり役に立たない。オブジェクト単位でデータを記憶でき る必要がある。即ちインスタンス変数である。C++で言えばメンバ変数だ。

Rubyの変数名ルール通り、一文字目が種別を決める。インスタンス変数は「`@`」 だ。

    class C
      def set_i(value)
        @i = value
      end

      def get_i()
        return @i
      end
    end

    c = C.new()
    c.set_i("ok")
    p(c.get_i())   # "ok"を表示する

インスタンス変数はこれまでの変数とはちょっと変わっていて、代入しなくて も（定義しなくても）参照できる。その場合どうなるかというと……前のコー ドの続きとしてこんなことをやってみた。

    c = C.new()
    p(c.get_i())   # nilと表示される

`set`せずに`get`してみたら、`nil`と表示された。`nil`というのは「ない」 を意味するオブジェクトである。そこにオブジェクトがあるのに ないというのも不思議だが、そういうものなのだからしかたがない。

`nil`はリテラルのように使うこともできる。

    p(nil)   # nilと表示される

### `initialize`

これまで見てきたように、定義したばかりのクラスでも`new`を呼べばインスタ ンスが作れる。それは確かにそうなのだが、クラス特有の初期化をしたいこと もあるだろう。そういうときは`new`を変えるのではなくて、`initialize`という メソッドを定義しておく。そうすると`new`の中でそれを呼んでくれる。

    class C
      def initialize()
        @i = "ok"
      end
      def get_i()
        return @i
      end
    end
    c = C.new()
    p(c.get_i())   # "ok"と表示される

ただ厳密に言うならこれはあくまで`new`というメソッドの仕様であって 言語の仕様ではない。

### 継承

クラスは他のクラスを継承できる。例えば`String`クラスは`Object`クラスを 継承している。本書ではこの関係を図3のように縦の矢印で書く。

図3: 継承

この図の場合、継承されるほうのクラス（`Object`）はスーパークラスとか 上位クラスと呼ぶ。継承したクラス（`String`）はサブクラスまたは 下位クラスと呼ぶ。この点C++とは用語が違うので注意してほしい。 Javaとは同じだ。

とにかく試してみよう。我々の作ったクラスにも他のクラスを継承させてみる。 クラスを継承して作るには（スーパークラスを指定するには）次のように書く。

    class C < SuperClassName
    end

これまでのようにスーパークラスを省略して書いたときは暗黙のうちに `Object`というクラスがスーパークラスになる。

さてなんのために継承するかと言えば、もちろんメソッドを引き継ぐためだ。 引き継ぐというのは、あたかもスーパークラスでのメソッド定義をサブクラス でもう一度繰り返したかのように働く、ということである。これも試してみよう。

    class C
      def hello()
        return "hello"
      end
    end

    class Sub < C
    end

    sub = Sub.new()
    p(sub.hello())   # "hello"を表示する

`hello`はクラス`C`で定義されたメソッドだが、`Sub`クラスのインスタンス に対しても呼ぶことができた。もちろん今度も変数に代入する必要はない。以 下のように書いても同じだ。

    p(Sub.new().hello())

同じ名前のメソッドを定義すればオーバーライドできる。C++や Object Pascal（Delphi）では予約語`virtual`などで明示的に指定したメソッド しかオーバーライドできないが、Rubyでは全メソッドが無条件にオーバーライ ド可能である。

    class C
      def hello()
        return "Hello"
      end
    end

    class Sub < C
      def hello()
        return "Hello from Sub"
      end
    end

    p(Sub.new().hello())   # "Hello from Sub"を表示する
    p(C.new().hello())     # "Hello"を表示する

またクラスは何段継承してもよい。例えば図4のように。こ の場合`Fixnum`は`Object`と`Numeric`と`Integer`のメソッド全て を引き継ぐわけだ。同名のメソッドがあるときはより近いクラスのメソッドが 優先される。型によるオーバーロードなんてものは一切ないので条件は非常に 単純である。

図4: 多段の継承

それと、C++だと何も継承しないクラスというものを作れるが、Rubyでは必ず `Object`クラスを直接または間接に継承しなければならない。つまり継承関係の 図を書くと`Object`を頂点とする一本のツリーになる。例えば基本ライブラリの 重要クラスの継承関係をツリーにすると図5のような感じだ。

図5: Rubyのクラスツリー

スーパークラスは一度（定義するときに）決めたらそれきりで、その後は 絶対に変えられない。つまりクラスツリーには新しいクラスが追加されること はあっても位置が移動したり削除されたりすることはない。

### 変数の継承……？

Rubyでは変数（インスタンス変数）は継承するものではない。継承しようにも、 そのクラスでどんな変数が使われるか、クラスには情報がないからだ。

だがメソッドさえ継承されればその継承したメソッドが呼ばれたときに（下位 クラスのインスタンスで）インスタンス変数への代入が起こる。つまり定義さ れる。そうすれば、インスタンス変数の名前空間はインスタンスごとに完全に フラットなので、どのクラスのメソッドからだろうとアクセスできるようにな る。

    class A
      def initialize()   # newの過程で呼ばれる
        @i = "ok"
      end
    end

    class B < A
      def print_i()
        p(@i)
      end
    end

    B.new().print_i()   # "ok"と表示される

この挙動が納得できないならクラスと継承を潰して考えてしまうといい。クラ ス`C`のインスタンス`obj`があるとしたら、まず`C`のスーパークラスのメソッ ドが全部`C`に定義されているとして考える。もちろんオーバーライドの規則 はちゃんと考慮しよう。そして今度は`C`のメソッドを`obj`にくっつけてしま う（図6）。この強烈な「モノ感」がRubyのオブジェクト指向の 特徴である。

図6: Rubyのオブジェクトのイメージ

### モジュール

スーパークラスは一つしか指定できなかった。つまりRubyは見ためには 単一継承のように見える。しかし実際にはモジュールがあるために 多重継承と同等の能力を持つ。次にそのモジュールについて説明しよう。

モジュールを一言で言えば、スーパークラスを指定できず、インスタンスも 作れないクラスだ。定義は次のように書く。

    module M
    end

これでモジュール`M`が定義された。メソッドもクラスと全く同じに 定義できる。

    module M
      def myupcase( str )
        return str.upcase()
      end
    end

しかしインスタンスが作れないので直接は呼び出せない。そこでどうする かと言うと、他のクラスに「インクルード」して使う。すると あたかもそのモジュールをクラスが継承したかのように扱うことができる ようになる。

    module M
      def myupcase( str )
        return str.upcase()
      end
    end

    class C
      include M
    end

    p(C.new().myupcase("content"))  # "CONTENT"と表示される

クラス`C`では何のメソッドも定義していないのに`myupcase`を呼び出すことがで きた。つまりこれはモジュール`M`のメソッドを「継承」したということである。 インクルードは機能的には継承と全く同じものだ。メソッド定義もインスタン ス変数のアクセスもなんら制限されない。

モジュールはスーパークラスを指定できない、と言ったが、 別のモジュールをインクルードすることならできる。

    module M
    end

    module M2
      include M
    end

つまりこれまた機能的にはスーパークラスを指定できるのに等しい。ただクラス が上位に来ることだけは決してない。あくまでモジュールの上にはモジュール だけが許される。

メソッドの継承も含めた例を以下に示す。

    module OneMore
      def method_OneMore()
        p("OneMore")
      end
    end

    module M
      include OneMore

      def method_M()
        p("M")
      end
    end

    class C
      include M
    end

    C.new().method_M()         # "M"が表示される
    C.new().method_OneMore()   # "OneMore"が表示される

クラスと同じように継承を書けば図7のようになる。

図7: 多段のインクルード

ところでクラス`C`にはスーパークラスもあるが、それとモジュールの関係はど うなるのだろう。例えば次のような場合を考えよう。

    # modcls.rb

    class Cls
      def test()
        return "class"
      end
    end

    module Mod
      def test()
        return "module"
      end
    end

    class C < Cls
      include Mod
    end

    p(B.new().test())   # "class"？ "module"？

`C`は`Cls`を継承し、`Mod`をインクルードしている。この場合、表示されるのは `"class"`だろうか、`"module"`だろうか。つまりモジュールとクラスのどちらが より「近い」のだろうか。RubyのことはRubyに聞け、ということで実行してみる。

    % ruby modcls.rb
    "module"

スーパークラスよりモジュールが優先されるようだ。

一般的に言うと、Rubyではモジュールをインクルードするとそのクラスと スーパークラスの「間」にはさまるような形で継承する。絵にするなら 図8のように書けるだろう。

図8: クラスとモジュールの相関関係

またモジュールにインクルードされているモジュールも考えれば 図9のようになる。

図9: クラスとモジュールの相関関係（2）

## プログラム（II）

注意。この節は非常に重要で、しかも静的な言語だけを使ってきたプログラ マにはなじみにくい要素を説明している。他は斜め読みでもいいが、ここだけ は注意して読んでほしい。説明も比較的丁寧に行う。

### 定数のネスト

まず定数について復習。大文字から始まるのが定数で、次のように して定義できた。

    Const = 3

そしてこの定数を参照するときは次のようにするのだった。

    p(Const)   # 3を表示する

実はこれは次のようにも書ける。

    p(::Const)   # 同じく3を表示する

頭に`::`が付くと「トップレベルで定義された定数である」ことを示す。ファイ ルシステムのパスに例えてみるといい。ルートディレクトリに`vmunix`というファ イルがあったとしよう。`/`にいるときは単に`vmunix`と書けばアクセスできる。 またフルパスで`/vmunix`と指定することもできる。`Const`と`::Const`もその関係 と同じである。トップレベルにいる間は単に`Const`と書いてもいいし、フルパ スで`::Const`と書いてもいい。

ではファイルシステムのディレクトリにあたるものはRubyではなんだろうか。 それはクラス定義文とモジュール定義文である。しかし二つあると長くて面倒 なので以後はまとめてクラス定義文で代表することにしておこう。そのクラス 定義文中では定数レベルが上がる（ディレクトリの中に入る）。

    class SomeClass
      Const = 3
    end

    p(::SomeClass::Const)   # 3と表示する
    p(  SomeClass::Const)   # 同じ。3と表示する

`SomeClass`はトップレベルで定義されたクラス即ち定数なので単に`SomeClass`と 書いても`::SomeClass`と書いても参照できる。そしてそのクラス定義にネスト している定数`Const`は「`SomeClass`の中にある」`Const`ということで、 `::SomeClass::Const`になる。

ディレクトリの中にまたディレクトリを作れるように、クラスの中でク ラスを作ることもできる。例えばこのように。

    class C        # ::C
      class C2     # ::C::C2
        class C3   # ::C::C2::C3
        end
      end
    end

ところで、クラス定義文の中で定義した定数は常にフルパスで書かなければいけな いのだろうか。もちろんそんなことはない。ファイルシステムの例えと同じで、 同じレベルのクラス定義文の「なか」にいれば`::`なしで参照できる。つま りこういうことである。

    class SomeClass
      Const = 3
      p(Const)   # 3と表示する
    end

あれっ、と思わなかっただろうか。なんと、クラス定義文中だろうと 実行されるプログラムが書けてしまうのである。静的な言語（だけ） に慣れている人だとこれは相当に意外だと思う。筆者も初めて見たときはギョッ とした。

いちおう付け加えておくと、もちろんメソッドの中からでも定数は見える。参 照規則はそのクラス定義文の中（メソッドの外）と全く同じである。

    class C
      Const = "ok"
      def test()
        p(Const)
      end
    end

    C.new().test()   # "ok"を表示

### 全ては実行される

ここで全体を見据えて一つ書いておこう。 Rubyではプログラムのほとんどの部分が「実行される」。 定数定義・クラス定義文・メソッド定義文やその他 ほとんどのものは見た通りの順番で、実行される。

例えば次のコードを見てほしい。 今までに使った構造をいろいろ使ってみた。

     1:  p("first")
     2:
     3:  class C < Object
     4:    Const = "in C"
     5:
     6:    p(Const)
     7:
     8:    def myupcase(str)
     9:       return str.upcase()
    10:    end
    11:  end
    12:
    13:  p(C.new().myupcase("content"))

このプログラムは以下の順番で実行される。

`1: p("first")` |  | `"first"`と表示する。 |
`3: < Object` |  | 定数`Object`を参照しクラスオブジェクト`Object`を得る |
`3: class C` |  | `Object`をスーパークラスとする新しいクラスオブジェクトを生成、定数`C`に代入 |
`4: Const = "in C"` |  | `::C::Const`を定義。値は`"in C"` |
`6: p(Const)` |  | `::C::Const`を表示。`"in C"`を表示する。 |
`8: def myupcase(...)...end` |  | メソッド`C#myupcase`を定義。 |
`13: C.new().myupcase(...)` |  | 定数`C`を参照し、それに対し`new`を呼び出し、さらにそれに対し`myupcase`を呼び出す。 |
`9: return str.upcase()` |  | `"CONTENT"`を返す。 |
`13: p(...)` |  | `"CONTENT"`を表示。 |

### ローカル変数のスコープ

これでようやくローカル変数のスコープについて話すことができる。

トップレベル、クラス定義文内、モジュール定義文内、メソッド本体、はそれぞれ 完全に独立したローカル変数スコープを持つ。つまり次のプログラムにある`lvar`は 全て別の変数であり、相互に行き来がない。

    lvar = 'toplevel'

    class C
      lvar = 'in C'
      def method()
        lvar = 'in C#method'
      end
    end

    p(lvar)   # "toplevel"と表示される

    module M
      lvar = 'in M'
    end

    p(lvar)   # "toplevel"と表示される

### コンテキストとしての`self`

以前、メソッドを実行中は自分自身（メソッドを呼び出したオブジェクト）が `self`になると言った。それは正しいのだが、半分でしかない。実はRubyプログ ラム実行中はどこにいようと`self`が設定されている。つまりトップレベルにも クラス定義文にも`self`があるのだ。

例えばトップレベルでも`self`がある。トップレベルの`self`は、`main`という。 なんの変哲もない、`Object`クラスのインスタンスだ。`main`は とりあえず`self`を設定するために用意されているだけで、 それ自体にあまり深い意味があるわけではない。

そんなわけでトップレベルの`self`即ち`main`は`Object`のインスタンスなの で、トップレベルでも`Object`のメソッドが呼べるということになる。そして `Object`には`Kernel`というモジュールがインクルードされており、そこで `p`や`puts`などの「関数風メソッド」が定義されている （図10）。だからこそトップレベルでも`p`や`puts`が呼べるのだ。

図10: `main`と`Object`、`Kernel`

だから本当は`p`も関数ではなくメソッドなのである。ただ、`Kernel`で定義され ているため、どこにいようと、つまり`self`のクラスがなんだろうと、「自分の」 メソッドとして関数のように呼べてしまうのだ。だからRubyには本当の意味で の「関数」は存在しない。あるのはメソッドだけである。

ちなみにそういう関数風メソッドには`p`や`puts`の他にも `print` `puts` `printf` `sprintf` `gets` `fork` `exec`などなど、 どこかで見たような 名前のものがたくさん存在する。このへんの名前の選びかたを見ると Rubyの性格がなんとなく想像できるのではなかろうか。

さて、どこにでも`self`が設定されているということはクラス定義文中にも 同じように`self`があるはずだ。クラス定義中の`self`はそのクラス （クラスオブジェクト）である。だからこんなふうになる。

    class C
      p(self)   # C
    end

これが一体何の役に立つのだろう。 実はもう非常に役立つ例を目にしている。これだ。

    module M
    end
    class C
      include M
    end

実はこの`include`はクラスオブジェクト`C`に対するメソッド呼び出しである。ま だ言っていないことだが、Rubyではメソッド呼び出しの括弧が省略できるのだ。 これまではクラス定義文の話が済んでいなかったので、メソッド呼び出しに見 えてしまわないようにあえて括弧を外しておいた。

### ロード

Rubyではライブラリのロードも全て実行時に行われる。 通常はこう書く。

    require("library_name")

見ためを裏切らず`require`はメソッドである。予約語ですらない。こう書くと こう書いた場所でロードが実行されて、そのライブラリ（のコード）に実行が 移る。Javaのパッケージのような概念はRubyにはないので、ライブラリ名の 名前空間を分離したいときはファイルをディレクトリに入れて分離する。

    require("somelib/file1")
    require("somelib/file2")

そしてライブラリの中では普通`class`文や`module`文でもってクラスなどを定義 するわけだ。トップレベルの定数スコープはファイルの別に関係なくフラット なので別のファイルで定義したクラスも最初から見える。クラス名の名前空間 を分離したいときは以下のように明示的にモジュールにネストさせる。

    # net ライブラリの名前空間分離の例
    module Net
      class SMTP
        # ...
      end
      class POP
        # ...
      end
      class HTTP
        # ...
      end
    end

## クラスについてさらに

### まだ続く定数の話

これまで定数のスコープをファイルシステムに例え てきたが、ここからはその例えはすっかり忘れていただきたい。

定数にはまだまだ仕掛けがある。 まず、「外」のクラスにある定数も見ることができる。

    Const = "ok"
    class C
      p(Const)   # "ok"を表示
    end

なぜこうなっているかと言うと、モジュールを名前空間として使うときに 便利だからだ。どういうことか、先程の`net`ライブラリの例に少し追加した もので説明しよう。

    module Net
      class SMTP
        # メソッドでNet::SMTPHelperを使う
      end
      class SMTPHelper   # Net::SMTPを補助するクラス
      end
    end

こういう場合、`SMTP`クラスの中からも`SMTPHelper`と書いただけで 参照できるほうが便利ではないだろうか。 そこで「外のクラスが見えると便利」という結論になるわけだ。

「外」のクラスは何段ネストしていても参照できる。同じ名前の定数が複数のネ ストレベルで定義されているときは、内側から順番に見ていって最初に見付かっ たものが参照される。

    Const = "far"
    class C
      Const = "near" # こちらのほうが上のConstより近い
      class C2
        class C3
          p(Const)   # "near"を表示
        end
      end
    end

また定数にはもう一つ検索パスがある。どんどん外のクラスを探していって トップレベルまで行っても見付からなかった場合は、さらに自分の スーパークラスの定数も見るのだ。

    class A
      Const = "ok"
    end
    class B < A
      p(Const)   # "ok"を表示
    end

全く、ややこしいことこのうえない。

まとめよう。定数を探すときは、まず外のクラスを探し次にスーパークラスを 探す。例えば、かなり作為的だが、以下のようなクラス階層があったとする。

    class A1
    end
    class A2 < A1
    end
    class A3 < A2
      class B1
      end
      class B2 < B1
      end
      class B3 < B2
        class C1
        end
        class C2 < C1
        end
        class C3 < C2
          p(Const)
        end
      end
    end

`C3`で定数`Const`を参照すると図11の順番で検索される。

図11: 定数の検索順序

一点注意。外のクラスのスーパークラス、例えば`A1`や`B2`は全く検索されない。 検索するのは、外ならあくまで外方向に向かってのみ、スーパークラス ならスーパークラス方向のみだ。でないととんでもない数のクラスを検索する ことになりかねないし、そんなに複雑なものは挙動が予測できない。

### メタクラス

オブジェクトならばメソッドを呼べる、と言った。呼べるメソッドはオブジェ クトのクラスで決まるとも言った。ならばクラスオブジェクトにも「そのクラス」 があるのだろうか（図12）。

図12: クラスのクラスは？

こういうときRubyでは実際に確かめてみることができる。 「自分の所属するクラス（クラスオブジェクト）を返す メソッド」`Object#class`があるからだ。

    p("string".class())   # Stringと表示された
    p(String.class())     # Classと表示された
    p(Object.class())     # Classと表示された

`String`は`Class`というクラスに所属しているらしい。 ではさらに`Class`のクラスはなんだろう。

    p(Class.class())      # Classと表示された

また`Class`らしい。つまりどんなオブジェクトだろうと `.class().class().class()`……と辿っていけば`Class`に行き着き、 そこでループにはまってどんづまりになる（図13）。

図13: クラスのクラスのクラスの……

`Class`はクラスのクラスだ。そして「○○の○○」という再帰構造を 持つもののことを「メタ○○」と言うから、`Class`は「メタクラス」 である。

### メタオブジェクト

では今度は対象を変えて、モジュールについて考えてみる。モジュールもやは りオブジェクトなので、クラスと全く同じように「そのクラス」があるはずだ。 見てみよう。

    module M
    end
    p(M.class())   # Moduleと表示される

モジュールオブジェクトのクラスは`Module`と言うらしい。 では`Module`クラスのクラスは何だろう。

    p(Module.class())   # Class

これまた`Class`だ。

それなら今度は方向を変えて継承関係を調べてみる。 `Class`と`Module`のスーパークラスはなんだろうか。 Rubyでは`Class#superclass`でそれを調べられる。

    p(Class.superclass())    # Module
    p(Module.superclass())   # Object
    p(Object.superclass())   # nil

なんと、`Class`は`Module`の下位クラスであった。 これらの事実からRubyの重要クラスの関係を図示すると 図14のようになる。

図14: Rubyの重要クラスの関係

今まで何の説明もなく`new`や`include`を使ってきたが、これでようやく正体を 説明できる。`new`は実は`Class`クラスで定義されたメソッドなのである。だから どんなクラスでも（`Class`のインスタンスだから）いきなり`new`が使えるわけだ。 しかし`Module`には`new`が定義されていないのでインスタンスが作れない。また `include`は`Module`クラスで定義されているから、モジュールに対してもクラスに 対しても`include`が呼べる。

この三つのクラス、`Object`、`Module`、`Class`はRubyの根幹を支えるオブ ジェクトたちだ。言ってみれば、この三つのオブジェクトがRubyのオブジェク ト世界自体を記述しているわけだ。つまりオブジェクトを記述するオブジェク トである。ならば`Object Module Class`はRubyの「メタオブジェクト」だ。

### 特異メソッド

オブジェクトならばメソッドを呼べる、と言った。呼べるメソッドはオブジェ クトのクラスで決まるとも言った。だが理念としてはメソッドはオブジェクトに 所属するのだということも言ったと思う。あくまでクラスは同じメソッドを 何度も定義してやる手間を省くための仕掛けだと。

そこでだ。実はRubyにはクラスとは関係なく個々のオブジェクト（インスタン ス）に対してメソッドを定義する仕組みもあるのだ。それにはこう書く。

    obj = Object.new()
    def obj.my_first()
      puts("My first singleton method")
    end
    obj.my_first()   # My first singleton methodと表示

知ってのとおり`Object`は全クラスのルートである。そんな重要クラスに `my_first`などという変な名前のメソッドが定義されているはずがない。そし て`obj`は`Object`のインスタンスである。しかし`obj`に対して`my_first`と いうメソッドを呼ぶことができる。つまり間違いなく、所属するクラスとは全 く全然なにも関係ないメソッドが定義されている。このような、オブジェクト ごとに定義されたメソッドのことを特異メソッド（singleton method）と 言う。

特異メソッドはどんなときに使うか。まずJavaやC++で言う スタティックメソッドの ようなものを定義するときだ。つまりインスタンスを生成しなくても使えるメ ソッドである。こういうメソッドはRubyではクラスオブジェクトの特異メソッ ドとして表現されるのだ。

例えばUNIXの`unlink`というシステムコールがある。ファイルのエントリをファ イルシステムから削除する命令だ。Rubyではこれをダイレクトに`File`クラスの 特異メソッド`unlink`として使えるようにしてある。それを使ってみよう。

    File.unlink("core")  # コアダンプを消す

いちいち「`File`オブジェクトの特異メソッド`unlink`」と言うのは面倒なので、 これからは単に「`File.unlink`」と書くことにする。間違えてこれを 「`File#unlink`」と書いたり、逆に「`File`で定義されたメソッド`write`」を 「`File.write`」と書いたりしないでほしい。

▼メソッド記法のまとめ

記法 |  | 呼び出せる対象 |  | 呼び出し例 |
`File.unlink` |  | `File`クラス自身 |  | `File.unlink("core")` |
`File#write` |  | `File`のインスタンス |  | `f.write("str")` |

### クラス変数

クラス変数は`ruby` 1.6から加わった、比較的新しい機能だ。定数と同じくクラ スに所属しており、クラスと、そのインスタンスの両方から代入・参照できる。 例を見てみよう。変数名の頭を`@@`にしたものがクラス変数である。

    class C
      @@cvar = "ok"
      p(@@cvar)      # "ok"を表示

      def print_cvar()
        p(@@cvar)
      end
    end

    C.new().print_cvar()  # "ok"を表示

クラス変数も最初の代入が定義を兼ねているので、次のように代入前に 参照すると実行時エラーになる。`@`こそ付くものの、インスタンス変数 とは振舞いがまるで違うのだ。

    % ruby -e '
    class C
      @@cvar
    end
    '
    -e:3: uninitialized class variable @@cvar in C (NameError)

ここではちょっと横着して`-e`オプションでプログラムを与えてみた。 `'`と`'`で囲まれている三行がプログラムだ。

またクラス変数は継承する。言いかたを変えると、下位クラスから上位 クラスのクラス変数を代入・参照できる。

    class A
      @@cvar = "ok"
    end

    class B < A
      p(@@cvar)            # "ok"を表示
      def print_cvar()
        p(@@cvar)
      end
    end

    B.new().print_cvar()   # "ok"を表示

## グローバル変数

最後に、いちおうグローバル変数もある。プログラムのどこからでも代入・参 照できるのがグローバル変数だ。変数名一文字目を`$`にしたのがグローバル変数 である。

    $gvar = "global variable"
    p($gvar)   # "global variable"と表示

グローバル変数はインスタンス変数と同じく、あらゆる名前が代入前に 定義されていると見做せる。つまり代入前に参照しても `nil`を返すだけでエラーにはならない。

御意見・御感想・誤殖の指摘などは 青木峰郎 <aamine@loveruby.net> までお願いします。

『Rubyソースコード完全解説』 はインプレスダイレクトで御予約・御購入いただけます (書籍紹介ページへ飛びます)。

Copyright (c) 2002 Minero Aoki, All rights reserved.