Rails

【Rails】使い所がいまいち分からないtapメソッドが実は便利だったので使い方をまとめてみる

Rails



 

今回は使い所がいまいちピンと来ないRails(Ruby)のtapメソッドが実は便利だったのでこの機会にまとめたいと思います。実際の開発では頻繁に使うメソッドではないと思いますが知っていれば便利なメソッドだったため、この機会に使い方を知っていただけたらと思います。

tapメソッドは古くからあるメソッドでRuby1.8.3から導入されています。

tapメソッドとは

tapメソッドとは、自身を引数にブロックを実行し自身を返すメソッドです。またtapメソッドはObjectクラスのメソッドであるため、Rubyで定義された全てのオブジェクトに対して使用することができます。

公式リファレンスには以下のように記載されています。

self を引数としてブロックを評価し、self を返します。メソッドチェインの途中で直ちに操作結果を表示するためにメソッドチェインに “入り込む” ことが、このメソッドの主目的です。

(1..10)                  .tap {|x| puts "original: #{x}" }
  .to_a                  .tap {|x| puts "array:    #{x}" }
  .select {|x| x.even? } .tap {|x| puts "evens:    #{x}" }
  .map {|x| x*x }        .tap {|x| puts "squares:  #{x}" }

参考: Ruby公式リファレンス Object#tap

動作確認

サンプルコードで動作を確認してみます。

tapメソッドはレシーバ自身を引数にブロック内に記述された処理を実行し、処理結果に関わらずレシーバ自身を返すメソッドです。

以下のサンプルコードを見ると、ブロック内では文字列の整形処理(HalloからHelloに整形)を行っていますが、p valueでは処理結果ではなくレシーバ自身(Hallo)が返却されていますね。

greeting = 'Hallo'
value = greeting.tap do |g|
  fixed_greeting = g.gsub(/Hallo/, "Hello")
  p fixed_greeting # 'Hello'
end

p value
=> 'Hallo'

応用的な使い方

破壊的メソッドで変更後のレシーバを返す

tapメソッドのブロック内で破壊的メソッドを使用することで、レシーバ自身ではなく処理結果を返却することができます。

以下のサンプルコードは、破壊的メソッドgsub!を用いてHalloからHelloに文字列を変換するプログラムになります。

greeting = 'Hallo'
value = greeting.tap do |g|
  fixed_greeting = g.gsub!(/Hallo/, "Hello") # 破壊的メソッドを使用
  p fixed_greeting # 'Hello'
end

p value
=> 'Hello' # 処理結果が返される
破壊的メソッドとは、レシーバであるオブジェクトそのものに変更を加えるメソッドです。非破壊的メソッドは、その場の実行結果のみに影響しますが、破壊的メソッドは自分自身に変更を加えます。

breakで処理結果を返す

tapメソッドのブロック内でbreakを使用することで、レシーバ自身ではなく処理結果を返却することができます。

以下のサンプルコードでは、breakによりHalloからHelloに文字列を変換した結果が返却されるプログラムになります。

greeting = 'Hallo'
value = greeting.tap do |g|
  break g.gsub!(/Hallo/, "Hello") # breakで処理を抜ける
end

p value
=> 'Hello' # 処理結果が返される
breakとは、繰り返し処理の中で実行すると繰り返し処理を終了させることができるメソッドです。

処理を1行で記述する

tapメソッドで複数行に渡るコードをスマートに記述できる場合があります。

以下のサンプルコードは、attributesをDBに保存し、ActiveRecordのインスタンス変数からidを取り出して返却するメソッドです。

def save_attributes
  model = Model.new(attributes)
  model.save # modelをDBに保存
  some_model.id # idを取り出す
end

 

上記では処理の中身が3行で記述されていますが、tapメソッドを用いることで1行で記載することができます。以下がそのサンプルコードになります。

def save_attributes
  Model.new(attributes).tap(&:save).id
end

まとめ

  • tapメソッドは自身を引数にブロックを実行し自身を返すメソッド
  • tapメソッドはObjectクラスのメソッドであるため、Rubyで定義された全てのオブジェクトに対して使用することができる
  • tapメソッドのブロック内で破壊的メソッドを使用することで、レシーバ自身ではなく処理結果を返却することができる
  • tapメソッドのブロック内でbreakを使用することで、レシーバ自身ではなく処理結果を返却することができる

参考

 

今回はRails(Ruby)のtapメソッドについて紹介しました。使い所がいまいちピンとこないメソッドでしたが、調べれば調べるほど面白いメソッドだなと感じました。実際の開発でも積極的に取り入れてみてください。