書くこと
Rubyのincludeについて、メソッド探索について学んだ結果見えた事実
こちらの記事を参考にさせていただきました。ありがとうございました。
【ruby】 メソッド探索から見る、モジュール・特異メソッド・特異クラス
自分なりに、こちらの記事を設計図と車で喩え直してみました。
(こちらの記事は、2部構成になっているうちの、第一部です。)
次の記事はこちら→
クラスとインスタンス
本題は、Rubyのincludeについてですが、この記事では後に理解がしやすくなるようにクラスとインスタンス、それに伴う変数とメソッドについて掘り下げていきます。
Rubyには、クラスとインスタンスと言う概念があります。
車を作る時で考えてみましょう。
- クラスは、設計図です。
- インスタンスは、その設計図をもとに作られた実際の車です。
もう少し理解してみましょう。クラスとインスタンスには、それぞれメソッドなるものが存在します。
- クラスメソッドは、設計図全体に適応される共通オプションです。
手引書のルールみたいなもんですね
- インスタンスメソッドは、それぞれの車の特徴・動作などをそれぞれに付け加えます。
車は「走る」、あの車は「赤い」などと言ったことを表します。
class Car #クラス
def color #インスタンスメソッド
@color = red #@colorはインスタンス変数と呼ばれます。@colorには、redが代入されています。
end
end
model_car = Car.new #Carクラスのインスタンスを生成し、model_carに代入しています。
model_car.color #Carクラスで定義されているcolorと言うインスタンスメソッドを、直前で生成したmodel_carインスタンスにかけています。
はい、ここまでは、多少Rubyについて勉強している方であれば、理解いただけたと思います。
わからない人も、ふーんと思いながら聞き進めてください。
本当に設計図と車の関係?
さて、ここから少しずつ、僕がなるほどなるほどと納得し直した部分に入っていきます。
まずは、先ほどのクラスとメソッドの関係性について
おさらいすると
####クラスは、設計図です。
インスタンスは、その設計図をもとに作られた実際の車です。
と端的に書きました。
設計図と車の関係であれば
「設計図通りの色や大きさ、エンジンなどの特徴・部品で車が作られる」
つまり、設計図に書いてある内容を、それぞれの車が持つことになります。
しかし、クラスとインスタンスの関係は、少し違うようなのです。
どのように違うのでしょうか?
実は常に「参照」している
結論から述べると
特徴や動作を**「持つ」のではなく、一回一回、設計図を「参照しながら」**車は、動いているのです。
ちょっとイメージが湧きにくいかと思いますので、先ほどのコードをもとに考えてみましょう。
class Car #Carクラスという設計図には、
def color #colorでredを呼び出せるインスタンスメソッドが存在します。
@color = red
end
end
model_car = Car.new #1
model_car.color #ここで、colorを呼び出しています。 #2
ここからが、最も大切な部分ですので、注意して読んでみてください。
まず、ここで何が起きているか順を追って説明します。
- model_car変数に、Carクラスのインスタンスが代入されます
- model_carインスタンスに、colorインスタンスメソッドを呼び出します。その結果、model_carオブジェクトはインスタンス変数の
@color
を持つことになります。
今の説明から、model_carと言う箱の中に、@color
があるということをイメージできるでしょうか。
しかし、その箱の中には、colorというインスタンスメソッドは存在しません。
つまり、**オブジェクトは@color
と言うインスタンス変数を持つことができるけど、colorというメソッドを持つことができない。**という結論になります。
そうすると、クラスがインスタンスメソッドを持つことになり、インスタンスはクラスのメソッドを常に参照することになりそうです。
まとめると
オブジェクトは インスタンス変数 と クラスへの参照 を持つ
クラスは インスタンスメソッド を持つ
と言うことができます。
No Method Errorが起きてしまうわけ
もう少しだけ話を膨らませます。
もし、このクラス(設計図)に、言及がないメソッドが呼び出されたらどうでしょうか?
class Car #Carクラスには、wheelメソッドは存在しません。
def color
@color = red
end
end
model_car = Car.new
model_car.wheel #wheelを参照しようとしています
# →No Method Error
このような状態で、No Method Errorが発生します。
このエラーが意味するところは
「そんな特徴は、設計図に書いてねーよ!」
ということです。次につながる話ですので、もう少し補足すると
「この設計図には書いてないから、この設計図の元になったものを追ってみよう。」
と判断させることもできます。
このことについては、次の記事で触れたいと思います。
最後に
最後まで読んでいただき、ありがとうございます。
ソースコード、記事の書き方について「もっとこうしたほうがいいよ!」というご意見、「そこどうなっているの?」というご質問など、お待ちしております。