【Ruby】非常に強力なRubyのクラス構成
Rubyのクラス構成は非常にシンプルで強力です。
クラス構成を理解することがそのままRubyを理解することにつながります。
Classクラス
RubyにはClassクラスというものが定義されています。
Rubyの組み込みクラスは全てClassクラスのインスタンスになります。
例えばObjectクラスやStringクラスなどがClassクラスのインスタンスです。
"Hello".class #String String.class #Class Object.class #Class
Rubyでは全てのクラスがnewメソッドを持っていますが、もちろん全てのクラスでnewメソッドを定義しているわけではありません。
Classクラスに定義して、それぞれのクラスで使用しています 。
Classクラスのメソッドを見ると、先程挙げたnewメソッドなど、クラスで共通して使われるメソッドが定義されていることがわかります。
Class.methods #[:nesting, :constants, :allocate, :new, :superclass 他省略
以下に図でClassとインスタンスの関係を示します。
特異メソッドとクラスメソッド
ところで、Rubyには特異メソッドというものがありました。
これはインスタンスに特有の振舞いを追加するものです。
class Test end a = Test.new b = Test.new #特異メソッド定義 def a.say_hello puts "Hello" end a.say_hello # Hello b.say_hello # NoMethodError
全てのクラスはClassクラスのインスタンスなので、クラスにも同様にして特異メソッドを定義できます。
class Test end #特異メソッド定義 def Test.say_bye puts "Bye" end Test.say_bye #bye String.say_bye #NoMethodError
クラスの特異メソッドとクラスメソッドは同じものであることに気がつくと思います。 クラスメソッドの定義方法を再度確認してみましょう。
class Test #クラスメソッド定義 def self.say_bye puts "Bye" end end Test.say_bye #bye String.say_bye #NoMethodError
インスタンス名がselfに変わっただけで、特異メソッドの定義方法と同様であることがわかります。
特異メソッドの定義場所
インスタンスがメソッドを呼び出すにはクラスに定義する必要があります。
では特異メソッドはどこに定義されているのでしょうか。
Rubyではインスタンス生成時に特異クラスというそのインスタンス専用のクラスを生成し、継承させています。
想像しづらいと思いますので図解します。
"Hello"という文字列はStringクラスのインスタンスですが、インスタンス生成時に"Hello"インスタンス専用のクラスが生成されます。
このクラスはStringクラスを継承しています。
これを"Hello"インスタンスの特異クラスといい、特異メソッドを定義するとこのクラスにインスタンスメソッドが定義されます。
特異クラスはsingleton_classというメソッドで確認できます。
特異クラスに定義されているメソッドを見てみましょう。
class Test end c = Test.new #特異メソッド定義 def c.say_hoge puts "hoge" end c.singleton_class.instance_methods false #[:say_hoge]
特異メソッドが特異クラスに定義されていることがわかります。
特異クラスはインスタンスのクラスと継承関係にあるので同名のメソッドはオーバーライドされます。
class Test def say_your_name puts "Test" end end d = Test.new def d.say_your_name puts "d" end d.say_your_name #d
Mix-inもそうでしたが、Rubyの処理はほとんどが継承関係、またはクラスとインスタンスの関係で説明がつきます。
このシンプルな構成がRubyの魅力の一つです。