🐷
[Feature #20786] then キーワードを使って処理をチェーンしたいという提案
[Feature #20786] Flow chaining with "then" keyword
-
then
キーワードを使って処理をチェーンしたいという提案 - どういうことかというと以下のようなコードに対して
def include?(other)
other = coerce_other(other)
return false unless other.family == family
begin_addr <= other.begin_addr && end_addr >= other.end_addr
end
- 以下のように
then
キーワードで処理結果を取得し、それに対してチェーンしていくらしい
def include?(other)
begin
coerce_other(other)
then => coerced # then => name で値を取得する
return false unless coerced.family == family
coerced
then => it
begin_addr <= it.begin_addr && end_addr >= it.end_addr
end
end
- 更に
begin
を省略したりit
を使った例も書かれています
def include?(other)
coerce_other(other)
then
it.family == family ? it : false
then
begin_addr <= it.begin_addr && end_addr >= it.end_addr
end
- 構文としては以下みたいなイメージみたいです
-
begin ~ end
の中でthen
を使って処理を分割する -
then
の直前の式の結果が真であれば次のthen
が呼び出されて式の結果が渡される -
begin ~ end
の結果は最後の式の結果が返ってくる
-
- パッと見、
#then
でチェーンすればいいんじゃない?と思ったけど偽の場合はスキップしたいので全く同じにはかけないのかな?
def include?(other)
coerce_other(other)
.then { |coerced|
coerced.family == family ? coerced : false
}
# 上の then の戻り値が false の場合は then を呼んでほしくない
.then { |it|
begin_addr <= it.begin_addr && end_addr >= it.end_addr
}
end
- 個人的にはよくわからん構文に見えるので普通に『偽のときはブロックは呼ばれない』
#then
メソッドとか定義するといいんじゃないかなー
module Kernel
def chain(...) = self.then(...)
end
class NilClass
def chain(...) = self
end
class FalseClass
def chain(...) = self
end
# これはブロックが呼ばれる
pp 42.chain { _1 + _1 }
# これはブロックが呼ばれず、レシーバを返す
pp nil.chain { 42 }
pp false.chain { 42 }
def include?(other)
coerce_other(other)
.chain { |coerced|
coerced.family == family ? coerced : false
}
# 上の chain が false を返した場合でもブロックが呼ばれない
.chain { |it|
begin_addr <= it.begin_addr && end_addr >= it.end_addr
}
end
- 個人的には新しい構文を追加するよりもこっちのほうがわかりやすいと思う
Discussion