Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyのselfキーワードとは?意味と使い方をわかりやすく解説

Rubyを学んでいると、「self」というキーワードの挙動に戸惑うことはありませんか。

どのように動作するのか、そもそもselfとは何なのでしょうか。

selfとは、現在のオブジェクトにアクセスするためのRubyのキーワードです。

この「現在のオブジェクト」が何を指すのかは、コードが置かれているコンテキスト(文脈)によって変わります。

コンテキストとは、その瞬間にコードがどこに存在しているかを指します。

selfの基本:コンテキストによって値が変わる

たとえば、コードがインスタンスメソッドの中にある場合、selfはそのクラスのインスタンス、つまりオブジェクトそのものを指します。

実際にコードを実行して確認してみましょう。

def coffee
  puts self
end

coffee
# main

このコードはcoffeeメソッドを定義して呼び出し、selfの値を出力します。

なぜ「main」と表示されるのでしょうか。

これはトップレベルオブジェクトの名前だからです。クラスの外側で定義されたメソッドは、すべてこのmainオブジェクトに属します。上記のcoffeeメソッドもその一例です。

一方、Catというクラスの中でメソッドを定義した場合は、selfCatのオブジェクトになります。

class Cat
  def meow
    puts self
  end
end

Cat.new.meow
# <Cat:0x7a14c5>

これらの例からわかるように、selfの値は使われる場所によって変化します。

さて、何かを深く理解するには、その目的を知るのが一番の近道です。selfにはどのような利点があるのでしょうか。具体的な例を見ていきましょう。

ローカル変数とメソッドの区別にselfを使う

selfの実用的な使い方のひとつは、同名のメソッドとローカル変数を区別することです。

変数とメソッドに同じ名前をつけるのは良い設計とは言えませんが、どうしてもそのような状況で作業しなければならない場合、self.メソッド名と書けばメソッドを明示的に呼び出せます。

class Example
  def do_something
    banana = "variable"

    puts banana
    puts self.banana
  end

  def banana
    "method"
  end
end

Example.new.do_something

# "variable"  => puts banana
# "method"    => puts self.banana

この例では、do_somethingメソッド内にbananaというローカル変数があり、同時にbananaというメソッドも定義されています。

Rubyではローカル変数が優先されるため、banana変数の値を出力するのではなく、bananaメソッドを呼び出したい場合にはselfが必要になるのです。

次に、より一般的なユースケースを見てみましょう。それはクラスメソッドの定義です。

クラスメソッドの定義にselfを使う

selfの用途として断トツでよく使われるのが、クラスメソッドの定義です。

def self.メソッド名という形式のメソッド定義を見たことがあるでしょう。

class Salad
  def self.buy_olive_oil
    # ...
  end
end

Salad.buy_olive_oil

ここでのselfは、クラス名であるSaladと同等です。

なぜこれが便利なのでしょうか。

各メソッド定義ごとにクラス名を書かなくて済むため、クラス名を変更したくなったときのコード修正が容易になります。また、コードがすっきりし、可読性も向上します。

そのため、def Salad.buy_olive_oilではなくdef self.buy_olive_oilと書くのが一般的なのです。

selfのその他の使い方

selfにはさらに多くの活用方法があります。慣れておくと非常に役立つ存在です。

たとえば、メソッド内で現在のオブジェクトと別のオブジェクトを比較できます。

def ==(other)
  self == other
end

また、デバッグ目的で「今扱っているオブジェクトが何か」を確認するのにも使えます。

p self

さらに、戻り値としてselfを返せば、ビルダーパターンのようなデザインパターンを実装できます。

class Salad
  def initialize
    @ingredients = []
  end

  def add_nuts
    @ingredients << :nuts

    self
  end
end

my_salad = Salad.new.add_nuts

selfの主な使い方まとめ

  • クラスメソッドの定義
  • 同名のローカル変数があるときにインスタンスメソッドを呼び出す
  • selfを返す(ビルダーパターン)
  • デバッグ
  • オブジェクトの比較(==)
  • メソッド呼び出しのデフォルトのレシーバ

selfとitselfの違い

最後に、もうひとつ知っておきたいのがKernel#itselfメソッドです。

これはオブジェクトに対して呼び出すと、そのオブジェクト自身を返すメソッドです。

[1,2,3,nil].select(&:itself)

# [1, 2 ,3]

この例では、配列からnilfalseが取り除かれます。

両者の違いを整理すると:

  • selfはキーワード。値はどこで使うかによって決まる
  • itselfはメソッド。値はどのオブジェクトに使うかによって決まる(1.itselfなら1が対象のオブジェクト)

参考になれば幸いです。

まとめ

この記事では、Rubyのselfキーワードについて、その正体・便利な理由・具体的な使い方を学びました。

ぜひ実際にコードを書いて試してみてください。

最後までお読みいただきありがとうございました!🙂

  1. Rubyのmapメソッド完全ガイド!配列・ハッシュのデータ変換を実例で解説

    Rubyのmapメソッドは、配列(Array)・ハッシュ(Hash)・範囲(Range)といったコレクションに対して使用できる強力なメソッドです。 mapの主な用途は、データの変換です。 例えば、文字列の配列があった場合、すべての文字列を順番に処理して、各文字を大文字に変換することができます。 また、Userオブジェクトのリストがある場合も同様です。 それらを変換して、対応するメールアドレスや電話番号など、Userクラスに定義された任意の属性のリストを作成できます。 それでは、具体的な使い方を見ていきましょう! Ruby mapメソッドの基本構文 mapの構文は次のようになっています。 a

  2. RubyのStructとOpenStructの使い方を徹底解説!値オブジェクトを簡単に作る方法

    Rubyには、関連する属性をまとめて保持する「値オブジェクト」を手軽に作れるStructという組み込みクラスが用意されています。本記事では、Structの基本的な使い方から注意点、そしてOpenStructとの違いまで詳しく解説します。 そもそもStructとは何か? StructはRubyに組み込まれたクラスで、新しいクラスを動的に生成し、値オブジェクト(Value Object)を作成するために使われます。値オブジェクトとは、関連性のある複数の属性をひとまとめにして扱うためのオブジェクトです。 具体例を挙げてみましょう。 2つの座標(xとy)を持つPointというデータを表したい場合、この