メタプログラミングRuby第2版 / 第5章クラス定義[勉強メモ]

メタプログラミングRubyを読んでいます。完全自分用のメモ記事です。
第5章の「クラス定義」で特に参考になった部分を中心に書いています。


🎳 5章クラス定義

カレントクラスとは?

- プログラムのトップレベルでは「カレントクラス」はmainクラスのObjectになる
- classキーワードでクラスをオープンするとそのクラスが「カレントクラス」となる
- メソッドの中では、カレントオブジェクトのクラスがカレントクラスとなる

class_evalを使ったメソッドの定義

def add_method_to(a_class)
a_class.class_eval do
def greet
puts 'Hello'
end
end
end
add_method_to String
'bcd'.greet #=> Hello

カレントクラスのまとめ

- Rubyのインタプリタはカレントクラスの参照を追跡する。defで定義されたメソッドはカレントクラスのインスタンスメソッドとなる
- クラス定義内では、カレントオブジェクト self と カレントクラスは同義である
- クラスへの参照を持っていれば、クラスはclass_eval(module_eval)でオープンできる

クラスインスタンス変数

class MyClass
@my_var = 1 # クラスインスタンス変数
def self.read
@my_var # クラスインスタンス変数
end
def write(arg_num)
@my_var = (arg_num) # インスタンス変数
end
def read
@my_var # インスタンス変数
end
end
obj = MyClass.new
obj.read #=> nil
obj.write(3) #=> 3
obj.read #=> 3
MyClass.read #=> 1

クラス変数の癖

@@v = 1
class MyClass
@@v = 2
end
puts @@v #=> 2

実行結果はこちら。

ruby xxx.rb
xxx.rb:1: warning: class variable access from toplevel
xxx.rb:7: warning: class variable access from toplevel
2

警告は出ているが、@@vの内容が書き換えられていることが分かる。

クラスメソッド

クラス・メソッドは『クラスの特異メソッド』。

class MyClass
def self.method
# メソッドの中身
end
end

確かにいわれてみれば、特異メソッドといえるかも。

👽 クラス拡張

次の実装をクラス拡張という。

module MyModule
def my_method; 'good evening'; end
end
class MyClass
class << self
include MyModule
end
end
MyClass.my_method #=> "good evening"

このクラス拡張のためのメソッドが、extend。(extendがなくても自分で実装できる)

module MyModule
def my_method; 'good morning'; end
end
class MyClass
extend MyModule
end
puts MyClass.my_method #=> "good morning"

🐠 サンプルソース

何かの役に立つこともあるかもですので、リポジトリも公開しておきます。

morizyun/meta_programming_ruby2 - GitHub

📚 おすすめの書籍

💩 欲しいものリスト公開しました