はじめに
こんにちは、現在アメリカの大学に行って語学を学びながらソフトウェアエンジニアになるために独学で勉強しているものです。
本日は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
をどのように使うべきかがよりクリアになったと思います。