Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
40
Help us understand the problem. What is going on with this article?
@viola

【Ruby】yield の役割

More than 3 years have passed since last update.

自分は yield をなかなか覚えられないでいます。分かったと思ったら、また忘れて考えています。もう一度理解した今、もう一度記事として書いておこうと思います。この事でつまづいている人の参考になれば幸いです。

まず yield とはどんな意味があるのか気になりました。きっと英単語に由来しているはずだろうと考え、大辞林で調べました。その意味はいくつかあるようです。

  • 生み出す・もたらす
  • 譲る・与える
  • 屈する・負ける
  • 取って代わられる

これらすべての言葉を使って説明できることに気づきましたので、まずサンプルとしてコードを書きます。

# yield を内包するメソッドを定義
def yield_mean?
  # ブロックを渡したのなら返す
  if block_given?
    yield( "Given Block. Example Code." )
  else
  # ブロックを渡さなかったのなら返す
    "Not Given Block."
  end
end

# ブロック付きで呼び出し
yield_mean? do | item |
  # このブロックが yield を評価する
  p item
end


# ブロックはないので yield は評価されない
p yield_mean?

このコードの出力結果は以下のようになります。

"Given Block. Example Code."
"Not Given Block."

yield_mean? を呼び出した時に使用したブロックパラメーターは、このメソッド内部に記述された yield の引数を示していることが分かります。この一連の流れはまさに大辞林で書かれていた意味と重なります。Ruby ではすべてがオブジェクトでしたね。ブロックさえもオブジェクトなのです。

yield はブロックにメソッド内部の式をもたらす・与える」「ブロックはそのメソッドのレシーバや引数からの流れ屈する形でメソッド内部の yield へつながる」「ブロックはそのメソッド内部の yield に取って代わられる」

この表現がすべて正しいのかは分かりませんが、このような感じではないかと考えています。

ブロックパラメーターの数が yield の引数よりも多かった場合には、その分だけ nil が得られます。逆に少ない場合は、単に呼び出されません。

def test_yield
  # 引数なしで全て nil
  yield
  # 多ければその数だけ nil
  yield(1)
  # 多ければその数だけ nil
  yield(1, 2)
end

puts "- a 引数ひとつ -"
test_yield do | a | p [a] end

puts "- a, b, c 引数みっつ -"
test_yield do | a, b, c | p [a, b, c] end

puts "- *a 引数を展開 -"
test_yield do | a, b | p [*a, *b] end

以下が yield から得られたオブジェクトを配列で見やすくまとめた出力の結果になります。

- a 引数ひとつ -
[nil]
[1]
[1]
- a, b, c 引数みっつ -
[nil, nil, nil]
[1, nil, nil]
[1, 2, nil]
- *a 引数を展開 -
[[]]
[[1]]
[[1, 2]]
40
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
viola
最近はROM専です。 投稿から1年以上経っている記事を参考する際は注意してください。場合によっては古すぎます。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
40
Help us understand the problem. What is going on with this article?