知っておくべきこと
Rubyにおけるクラスとは
Rubyにおけるクラス定義は「コードを実行する」ということだ。JavaやC#ではクラスを定義してもそのクラスのオブジェクトを生成して、メソッドを呼び出すまで何も起きない。しかし、Rubyでクラスを定義するということはオブジェクトの動作を規定することではなく、コードを実行するということなのだ。
クラスインスタンス変数 & クラス変数
クラスインスタンス変数
1 2 3 |
|
こういうふうにクラスにもインスタンス変数が定義できる。ここの@my_var
はクラス定義の中にあるのでクラスに属している。
だからクラスのオブジェクトのインスタンス変数とは別物ということだ。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
上記のコードには2つのインスタンス変数を定義している。どちらも@my_var
という名前だ。しかし、それぞれ異なるスコープに定義されており、別々のオブジェクトに属している。上記のコードのMyClass
のオブジェクトのobj
はMyClass
クラスのインスタンス変数の@my_var
は呼べない。同じくobj
の外側からもobj
のインスタンス変数の@my_var
が呼べないのだ。
こういうふうにクラスがself
となる場所に定義されているインスタンス変数をクラスインスタンス変数と呼ぶ。
クラス変数
クラス変数は@@
をつけて定義できる。
1 2 3 |
|
これはクラスインスタンス変数とは違う。サブクラスや通常のインスタンスメソッドからもアクセスできる。
1 2 3 4 5 |
|
しかし、クラス変数の使いには少し気をつけないといけないところがある。
1 2 3 4 5 6 7 |
|
@@v
の値が変わるのはこのクラス変数がクラスではなく、クラス階層に属しているからだ。@@v
はmain
のコンテキストに定義されているので、main
のクラスであるObject
の全ての子系にも属しているということになり、全部同じクラス変数を共有しているからだ。
特異メソッド
特異メソッド
Rubyでは、特定のオブジェクトにメソッドを追加できる。
1 2 3 4 5 6 7 8 9 |
|
上記のコードはtitle?
メソッドを文字列str
に追加している。String
クラスの他のオブジェクトには影響はない。
こうしたあるオブジェクトに特化したメソッドのことを特異メソッドと呼ぶ。
クラスメソッドの真実
クラスメソッドはクラスの特異メソッドである。
1 2 3 4 5 6 7 |
|
上記の2つの定義は同じものなのだ。
1 2 3 |
|
上記のobject
の部分にはオブジェクトの参照、クラス名の定数、selfのいずれかが使える。つまり、クラスメソッドはselfを使った特異メソッドである。
クラスマクロ
Module#attr_*()
族のメソッドを使えば、一気にオブジェクトに対するアクセサを生成できる。
Module#attr_reader
は読み取り用、Module#attr_writer
は書き込み用、Module#attr_accessor
は読み書き両用だ。
コードで見てみると
1 2 3 4 5 |
|
NoMethodErrorが出てしまう。
1 2 3 4 5 6 7 8 9 |
|
name
のメソッドは読み込めるが、アクセスはできない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
これでインスタンス変数の@name
にアクセスできる。
これはこうもかける。
1 2 3 4 |
|
そして、
1 2 3 4 5 6 7 8 9 10 11 |
|
こう使える。
このようなメソッドをクラスマクロと呼ぶ。
クラスマクロはキーワードのように見えるが、クラス定義の中で使えるクラスメソッドである。
&Check
&Checkでのクラスメソッド
form
クラスでよくクラスメソッドを使っている。
- 例
1 2 3 4 5 6 7 8 9 10 11 |
|
&Checkでのクラスマクロ
form
, service
, usecase
などで幅広く使われている。(attr_accessor
, attr_reader
)
- 例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
全然関係ないけど気になるやつ
delegate
上記のコードの中でdelegate
というのがあったけど、delegate
は何物か気になったから調べておく。
delegate
はhas_one, through
と似たようなもので、to
で指名しているオブジェクトからの関係あるモデルを呼び出せるらしい。
上記ではto
で:burden
を指名しているから、:burden
の関係モデルの中のcommenter
を持ってこれる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
上記のコードでわかるように渡されるburden
はQualitative::SurveyGroupComment
のオブジェクトである。
だから、delegate
を使ってQualitative::SurveyGroupComment
オブジェクトの関係モデルのcommenter
オブジェクトを呼び出すことができるということだ。
1
|
|
のように使える。
次の記事
第4章 クラス定義の残った分量の
- 特異クラス
- アラウンドエイリアス
あと、
- 第5章「コードを記述するコード」