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

【完全ガイド】Rubyのyieldとyield_selfの違いを徹底解説

Rubyにおける「yield」というキーワード、名前は知っていても、実際に何をするものなのか曖昧なままの方は多いのではないでしょうか。

結論から言うと、yieldはRubyのキーワード(言語の中核を構成する要素)の一つで、メソッド内からブロックを呼び出すために使われます。

押さえておきたいポイントは以下の3つです

  • ブロックを呼び出すと、そのブロック内のコードが実行される(メソッド呼び出しと同じイメージ)
  • yieldは任意の数の引数をブロックに渡せる
  • ブロックの戻り値がそのままyieldの戻り値になる

yieldを理解するには、まず「ブロック」の概念を把握しておく必要があります。

ブロックとは、名前のないメソッドのようなもので、他のメソッドへ追加の引数として渡せるコードのかたまりだと考えると分かりやすいでしょう。

実際のコード例を見てみましょう

def make_salad
  yield "lettuce"
  yield "carrots"
  yield "olive oil"
end

make_salad { |ingredient| puts "Adding #{ingredient} to salad!" }

このコードではブロックが3回呼び出され、次のような出力が得られます

Adding lettuce to salad!
Adding carrots to salad!
Adding olive oil to salad!

これがyieldの本質です。動作はメソッド呼び出しに似ていますが、代わりにブロックを呼び出している点が異なります。ブロックには名前がないため、このキーワードがその役割を担っているのです。

さて、次にブロックが存在しない場合に何が起こるのかを見ていきましょう。

ブロックなしでyieldを呼ぶとエラーになる

ブロックが渡されていない状態でyieldを呼び出すと、エラーが発生します。

def write_code
  yield
end

write_code

# LocalJumpError: no block given (yield)

エラーメッセージは非常に明快です。「no block given(ブロックが渡されていない)」は、write_codeメソッドの呼び出し時にブロックが提供されていないことを意味します。

では、このエラーを防ぐにはどうすればよいのでしょうか?

答えはこれです:

def write_code
  yield if block_given?
end

block_given?メソッドはブロックが利用可能かどうかをチェックするため、trueの場合のみyieldを実行するように制御できます。

yieldを使うメリットとは?

yieldを使うことで、ブロックという強力な仕組みを活用できます。

ブロックは、メソッド呼び出しの一部としてコードの断片を渡すために使われます。

具体的には、こんな場面で役立ちます

  • コードの実行時間を計測してログに出力する、汎用的なロギング関数を作りたいとき
  • メソッドの処理完了後に特定のコードを実行したいとき(JavaScriptでいう「コールバック」のようなもの)
  • 必要なときだけ実行される「遅延評価のコード」を実現し、ユーザー側でカスタマイズできるようにしたいとき(具体例としてはHash#fetchメソッドの挙動を参照してください)

とても便利ですね!

yield_selfとの違いは何?

yield_selfというメソッドを見かけたとき、「yieldと関係があるのでは?」と思うかもしれません。

しかし、実はまったく別物です。

yield(self)とも異なります。selfは現在のオブジェクトを参照するためです。

一方、Ruby 2.5で導入されたyield_selfは、メソッドを呼び出した対象のオブジェクトそのものを扱います。

このメソッドの効果的な使い道は?

メソッドチェーンを行いながら、yield_selfを呼び出したオブジェクトに対して何らかの処理を適用したいときに使います。

そして、元のオブジェクトではなく処理結果を返すのがポイントです。

n_squared = ->(n) { n ** 2 }

2
.yield_self(&n_squared)
.yield_self(&n_squared)

# 16

なお、Ruby 2.6ではyield_selfのエイリアスとしてthenメソッドが追加されました。

ただし、通常のyieldと混同しないよう注意してください。

Railsでのyieldの使われ方

Railsやテンプレートエンジンにおけるyieldの使い方についても簡単に触れておきましょう。

Railsのレイアウトファイルにはyieldが含まれています。

Railsはこのyieldを、レンダリング対象のビューの内容で置き換えます。

yieldがないと、レイアウトは空になってしまいます!

これこそが、レイアウトとビューが組み合わさる仕組みなのです。

まとめ

この記事では、Rubyのyieldキーワードについて学びました。それが何であり、どのように動作し、なぜ重要なのかを理解できたはずです。

ぜひご自身のRubyコードで試してみてください。

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

  1. Rubyで実践する関数型プログラミング完全ガイド ― 純粋関数・イミュータブルデータ・カリー化の基本

    Rubyを書いていると、「関数型プログラミング」という言葉を目にする機会が増えてきます。しかし、実際にどんなものなのか、自分のコードに取り入れるべきなのか、疑問に感じている方も多いのではないでしょうか。 関数型プログラミングとは、具体的に何を指すのか? オブジェクト指向プログラミング(OOP)とは何が違うのか? Rubyでも関数型的な書き方を採用すべきなのか? この記事では、これらの疑問にわかりやすく答えながら、Rubyで今日から使える関数型プログラミングの考え方とテクニックを解説します。 関数型プログラミングとは? 関数型プログラミングは一時的な流行や難しい専門用語ではなく、長い歴史を持

  2. Fitbit Pay完全ガイド:設定方法からお支払い・セキュリティ対策まで徹底解説

    Fitbitは、最も優れたスマートウェアラブルデバイスのひとつです。多彩なモデルと豊富な機能を備えており、その中でも人気の高い機能が「Fitbit Pay」です。Fitbit IonicやFitbit Versaに搭載されたNFC(近距離無線通信)チップにより、非接触決済に対応したあらゆる店舗で、腕時計をつけたまま支払いが可能になります。 この記事では、Fitbit Payの使い方をマスターできるよう、設定方法からセキュリティ対策まで完全ガイドとして詳しく解説します。 Fitbit Payとは? Fitbit Payは、デビットカードやクレジットカードをFitbit IonicおよびVersa