Rubyでは既存のクラスを再定義することができる。これを「オープンクラス」と読んだりします。
例えば配列の合計値を求めたい場合。Arrayクラスにはsumメソッドは無いので新しくメソッドを作る必要があります。
array = [1,2,3,4,5] def sum(array) array.inject(:+) end p sum(array)
15
このようなsumメソッドを作成するのもいいのだが、Rubyならもっとスマートに解決できる方法がある。
改良版
array = [1,2,3,4,5] class Array def sum self.inject(:+) end end p array.sum
15
こんな感じでArrayクラスにsumを定義させることでスマートにsumメソッドを記述することができるようになるのである。
ここでintroductionメソッドを新たに作成し、そのメソッド内のselfを確認してみる。
array = [1,2,3,4,5] class Array def introduction puts "myself is #{self}" puts "my class is #{self.class}" end end array.introduction
myself is [1, 2, 3, 4, 5] my class is Array
上の実行結果からintroductionメソッド内でのselfは呼び出された配列であることがわかる。そして配列のクラスはArrayクラスである
オープンクラスの問題点
オープンクラスの問題点としては、既存のクラスに元から存在していたメソッドを上書きしてしまうといったことがある。そうならないようにするためには、メソッドを定義するまえにmethod_defined?などで確認などを行なっておくとよいです。
array = [1,2,3,4,5] class Array unless method_defined?(:each) def each self.times{ "hello" } end else puts "each method has already been defined" end end array.each do |n| puts n end
each method has already been defined 1 2 3 4 5
ちゃんとeachメソッドを守ることが出来ました。