読者です 読者をやめる 読者になる 読者になる

Programming log - Shindo200

イベント参加記録とプログラミング系の雑記

Ruby2.2で新たに加わったitselfメソッドについて

2014年12月25日にRuby2.2.0がリリースされました。Rubyがアップデートされるたびに、新機能の紹介エントリを書いていたのですが、今回はitselfメソッドの追加が気になりましたので、このメソッドだけに絞ってエントリを書きます。

Kernel#itself

itselfメソッドはレシーバ自身を返すだけのメソッドです。Ruby2.2.0未満のバージョンでも、以下のように実装することで、itselfメソッドを使うことができます。

class Object
  def itself
    self
  end
end

実は、ActiveSupport4.2.0にもこっそりと追加されていますので、Rails4.2.0以降を使っていれば、Ruby2.2.0未満でもitselfメソッドを使うことができます。

ところで、このメソッドはどのような場面で使うのでしょうか。RailsAPIドキュメントを参考にして、ユースケースを考えてみました。

ユースケース

例えば、ActiveRecordを使って、あるモデルの全てオブジェクトを取得する処理があるとします。
基本的には全てのオブジェクトを取得してほしいのですが、ユーザーがオプションとして取得条件を付けたときだけは、その条件で絞り込みを行って欲しいとします。この場合、今までは以下のように実装していたかと思います。

# Model
class Entry
  scope :published, lambda do
    # 公開済み記事のみを取得する条件が書かれたスコープ
  end

  scope :drafted, lambda do
    # 下書き記事のみを取得する条件が書かれたスコープ
  end
end

# Controller
class EntriesController
  def index
    @entries = Entry
    # 「公開済み記事のみ」か「下書き記事のみ」で絞り込むように指定されているならば、絞り込みを行う
    if state.presence_in(%w(published drafted))
      @entries.public_send(state)
    end
    @entries.order(:created_at)
  end
end

このままでも複雑ではありませんが、itselfメソッドを使うことで、このようにコーディングできるようになりました。

# Model
# 先ほどと同じなので省略

# Controller
class EntriesController
  @entries = Entry.public_send(state.presence_in(%w(published drafted)) || :itself).order(:created_at)
end

いかがでしょうか。public_sendメソッドやsort_byメソッドなど、メソッド名を引数とするメソッドのデフォルト値としてitselfメソッドを使うと良いのではないでしょうか。

以上、itselfメソッドの紹介でした。

2015/01/22 記事修正

エントリ公開当初のコード。

# Controller
class EntriesController
  @entries = Entry.public_send(params[:state].presence_in(%w(published drafted)) || :itself).order(:created_at)
end

「presence_inメソッドで値をチェックしているとはいえ、paramsの値をそのままpublic_sendメソッドの引数に使うのは怖いのでは?」という意見をいただきまして、コードを修正しました。