9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Object#tapでbreak(値)すると値を返せる、のはなぜ?

Last updated at Posted at 2017-07-06

image.png

公式っぽいドキュメントにはbreakしたら値が戻るとは書いてないんだけど、なぜかそうなる裏テク。
https://www.google.co.jp/search?q=rails+tap+break

コード見ても元のobjが返りそう。
なんでなんで。
rb_yieldはobjを書き換えるのか?

yieldしたprocの中でbreak

def aaa
  yield
  return "123"
end

aaa{ break "456" } #=> "456"

これだー。
絶対"123"しか返さなさそうなaaaが"456"を返す。
https://docs.ruby-lang.org/ja/latest/doc/spec=2fcontrol.html#break

でもそんなこと書いてない。裏テク?

ブロックの中から 制御構造/break により中断された場合

ブロック付きメソッドの戻り値は、通常のメソッドと同様ですが、ブロックの中から 制御構造/break により中断された場合は nil を返します。

break に引数を指定した場合はその値がブロック付きメソッドの戻り値になります。
https://docs.ruby-lang.org/ja/latest/doc/spec=2fcall.html#block

これだなあ。
callbackとして渡したblock内でまちがってbreakすると意図しないreturnになっちゃうということだ。
やっぱり裏テクだった。

Object#as

class Object
  def as
    yield self
  end
end

キレイでよさそう。

> "1112222".delete("-").as{|x| x[0,3] + "-" + x[3,4]}
=> "111-2222"

> "111-2222".delete("-").as{|x| x[0,3] + "-" + x[3,4]}
=> "111-2222"

> "111-2222".delete("-").tap{|x| break(x[0,3] + "-" + x[3,4]) }
=> "111-2222"

> "1112222".delete("-").tap{|x| break(x[0,3] + "-" + x[3,4]) }
=> "111-2222"
9
3
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?