酒と泪とRubyとRailsと

Ruby on Rails と Objective-C は酒の肴です!

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

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


5章 クラス定義

カレントクラスとは?

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

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

1
2
3
4
5
6
7
8
9
10
11
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)でオープンできる

クラスインスタンス変数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

クラス変数の癖

1
2
3
4
5
6
7
@@v = 1

class MyClass
  @@v = 2
end

puts @@v #=> 2

実行結果はこちら。

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

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

クラスメソッド

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

1
2
3
4
5
class MyClass
  def self.method
    # メソッドの中身
  end
end

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

クラス拡張

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

1
2
3
4
5
6
7
8
9
10
11
module MyModule
  def my_method; 'good evening'; end
end

class MyClass
  class << self
    include MyModule
  end
end

MyClass.my_method #=> "good evening"

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

1
2
3
4
5
6
7
8
9
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


おすすめの書籍