Rubyのクラスオブジェクトについて 1

環境

ruby-2.0.0-p247

パーフェクトRubyのクラスオブジェクトのところをかいつまんで読んでみたまとめ的な感じ。

クラスを定義する

class式を使うのとClass#newで定義できる。

class Hoge
end
a = Class.new

Class#newを使う場合は無名クラスというものになるらしい。
二つとも"クラス"なので継承とか普通にできる。
違うことは、class式だと定義時に外のローカル変数が見えない。

name = "koji"

Class.new { p name } # "koji"

class C
  puts name # `<class:C>': undefined local variable or method `who' for C:Class (NameError)
end

Rubyのクラスは、Class#newでわかるようにClassクラスのインスタンスになってる。
class式を使うと渡した定数にClassオブジェクトを割り当てているとのこと。

クラスインスタンス変数

インスタンス変数でもクラス変数でもないくて、クラスインスタンス変数。

class式のトップレベルに書く ”インスタンス変数"はクラスインスタンス変数というものになる。
Classインスタンスインスタンス変数みたいな感じ。(違うかも)

class Hoge
  @foo = :foo
  @@bar = :bar

  def initialize
    @go = 24
    @hoge = :hoge
  end
end

hoge = Hoge.new
p hoge.instance_variables  # [:@go, :@hoge]
p Hoge.class_variables     # [:@@bar]
p Hoge.instance_variables  # [:@foo]

トップレベルに定義している@fooはClassクラスのインスタンス変数であるため、
Hoge.instance_variablesで出てきている。(Hogeの中身はClassクラスのインスタンス。)

クラスインスタンス変数とクラス変数の違い

クラスインスタンス変数とクラス変数はHogeクラスに属しているため、参照される範囲は同じ。
違うことは、このHogeクラスを継承しているクラスからは、クラスインスタンス変数の読み書きができない。

メソッドを定義する

メソッドの定義にはdef式とdefine_methodメソッドのどちらかでできる。

a = Class.new do
  define_method :foo, -> { :foo } # instance method
end

class << a
  define_method :goo, -> { :goo } # class method
end

a.class_eval { define_method :bar, -> { :bar } } # instance method
a.class_eval { define_singleton_method :bue, -> { :bue } } # class method

define_methodの第一引数にはメソッド名となる値、第二にはprocかMethodオブジェクトを渡す。

続く