はじめに
こんにちは、現在アメリカの大学に行って語学を学びながらソフトウェアエンジニアになるために独学で勉強しているものです。
本日はRubyを勉強しているとよく出てくる、メソッドについて整理していきます。
というのも、現在progate→ゼロから分かるRuby→たのしいRubyと段階を追って勉強しているのですが、レシーバについて詳しく触れる機会がなく何となくでここまで進んでしまっているので
railsに入る前に定義をしっかり確立していきたいと思います。
レシーバ
レシーバとは、メソッドが呼び出される際に、そのメソッドを実行するオブジェクトです。
オブジェクト指向プログラミングでは、オブジェクトが持つメソッドを呼び出す際、どのオブジェクトに対してメソッドを実行するのかをレシーバが決定します。
str = "hello" # str は String クラスのオブジェクト
str.upcase # str がレシーバとなり、upcase メソッドが呼ばれる
ここでは、helloというStringオブジェクトのupcaseメソッドを呼び出しています。
この場合、strがレシーバです。メソッドがレシーバに対して何らかの操作を行い、その結果が返されます。
selfとは
次に、 selfについて説明します。
selfは、そのメソッドが実行されるオブジェクト、もしくはクラスを指す特殊な変数です
selfは現在のレシーバ(メソッドを呼び出しているオブジェクト)であるということと省略できる場合があります。
できない場合も後で説明するのでまずはこの2つを覚えておいてください。
まずは省略できるケースから紹介します
selfが省略できるケース
selfが省略できるのはインスタンスメソッドの場合です。詳しく見ていきましょう。
class Person
def greet
puts "Hello!"
end
end
person = Person.new
person.greet # => "Hello!"
この例では、personインスタンスを生成して、greetメソッドで呼び出しています。
greetはインスタンスメソッドと呼ばれ、呼び出す場合にはselfを使用しないでも大丈夫です。
これはRubyが現在のレシーバであるインスタンス(今回はperson)をselfとして解釈してくれるからです。
selfが省略できないケース
クラスメソッドを使う場合はselfを省略することができません。※
どういうことか詳しく見ていきましょう
class MyClass
def self.greet
"Hello from the class!"
end
end
puts MyClass.greet # => "Hello from the class!"
この例では、greetメソッドをself.greetと定義しています。
これにより、greetはクラスメソッドになり、MyClassというクラス自身に対して呼び出すことができます。
※クラス名を直接使って定義する方法もありdef MyClass.greetと書くことでもクラスメソッドを定義できます
この場合、greetの前にselfを置かないとエラーになります。なぜでしょうか。
クラスメソッドでselfが必要な理由
Rubyでは、クラス内でメソッドを定義する際に、何も指定しなければそのメソッドはインスタンスメソッドとして定義されます。
インスタンスメソッドの場合、インスタンスが暗黙のレシーバとなるため、selfを省略してもインスタンスが自動的にレシーバとして認識されます。
一方で、クラスメソッドを定義する際には、クラス自体がレシーバになることを明確にする必要があります。クラスメソッドの場合、selfはクラスそのものを指します。self.greetと書くことで、greetメソッドがインスタンスではなくクラスに対して実行されることを示します。
もしselfを付けずに単にgreetと書いてしまうと、Rubyはそれをインスタンスメソッドとして解釈しようとし、エラーが発生します。なぜなら、この場合、レシーバとなるインスタンスが存在しないからです。
クラスメソッドとインスタンスメソッドの違い
ここで、クラスメソッドとインスタンスメソッドの違いを改めて整理します。
クラスメソッドはクラスそのものに属するメソッドであり、クラスに対して直接呼び出されます。
一方、インスタンスメソッドはクラスのインスタンス(オブジェクト)に属し、そのインスタンスに対して呼び出されます。
クラスメソッド: MyClass.greet
インスタンスメソッド: my_instance.greet
この違いを意識することで、selfが必要なタイミングをより正確に理解できるようになります。
もしクラスメソッドとインスタンスメソッドの違いについて知りたい方は、記事を書いているのでそちらを見ていただけたら幸いです
まとめ
今回の記事では、レシーバとselfの役割や使い方について説明しました。
レシーバは「どのオブジェクトがメソッドを実行するか」を決め、selfはそのレシーバを明示的に指し示すものです。
また、クラスメソッドとインスタンスメソッドの違いも把握することで、selfをどのように使うべきかがよりクリアになったと思います。