クラス定義、クラスインスタンス変数、特異メソッド

クラス定義の中身

クラス定義では、クラスがカレントオブジェクトselfの役割を担う。

class MyClass
  puts 'hello!'
end

次のようにも書ける

result = class MyClass
  self
end
result # => MyClass

Rubyのプログラムは常にカレントオブジェクトselfを持っている。また、常にカレントクラスを持っている。カレントオブジェクトはselfで参照できるがカレントクラスはキーワードがない。カレントクラスを参照するにはclassキーワードでクラスをオープンする。
クラス名がわからないときはclassキーワードは使えないのでclass_evalメソッドを使う。
以下のコードは既存のクラス(String)のコンテキストでブロックを評価する。

def add_method_to(a_class)
  a_class.class_eval do
    def m; 'Hello!'; end
  end
end

add_method_to(String)
"abc".m #=> "Hello!"

クラスインスタンス変数

クラスのインスタンス変数はクラスのオブジェクトのインスタンス変数とは別物である。このあたりはとてもわかりにくい

class MyClass
  @my_var =1

  def self.read; @my_var; end
  def write; @my_var=2; end
  def read; @my_var; end
end

obj = MyClass.new
obj.write
obj.read #=>2
MyClass.read #=>1

二つ目の@my_var(self.read)はMyClassがselfとなる場所に定義されている。これはMyClassオブジェクトのインスタンス変数でクラスインスタンス変数と呼ばれる。

特異メソッド

Rubyでは特定のオブジェクトにメソッドを追加できる

str = "test strings"
def str.title?
  self.upcase == self
end

str.title?                             #=> false
str.methods.grep(/title?/)  #=>["title?"]
str.singleton_methods       #=>["title?"]

title?メソッドを文字列strに追加している。他のStringクラスのオブジェクトには影響がない。このあるオブジェクトに特価したメソッドのことを特異メソッドと呼ぶ。