【一人 bugs.ruby Advent Calendar 2021】[Feature #17576] Partial Functions (procs, lambdas)【2日目】
【一人 bugs.ruby Advent Calendar 2021】[Feature #17576] Partial Functions (procs, lambdas)【2日目】
一人 bugs.ruby Advent Calendar 2021 2日目の記事になります。
今回はブロック構文に in
を使ったガード節を追加する提案です。
[Feature #17576] Partial Functions (procs, lambdas)
ブロック構文に in
を使ったガード節を追加する提案です。
以下のように in
を使ってガード節がかけるようになります。
partial_proc = proc do |arg| # ここの `in x if x.odd?` の部分がガード節の条件になります。 in x if x.odd? "#{x} is odd" end
このような Proc
オブジェクトに対して以下のように Proc#defined?
や Proc#call_or_else
を使えるようにする感じらしい。
# `defined?` で引数が有効かどうかを判定する partial_proc.defined?(42) #=> false partial_proc.defined?(41) #=> true # call で実際に呼び出す # 該当するガード節がない場合は例外が発生する partial_proc.call(42) #=> raises NoMatchingPatternError (42) partial_proc.call(41) #=> 41 is odd # call_or_else で見つからなかった場合の挙動をブロックに記述する partial_proc.call_or_else(42) { "fallback value" } #=> 'fallback value' partial_proc.call_or_else(41) { "fallback value" } #=> 41 is odd
これを用いて FizzBuzz
を書くと多分以下のような感じですかね?
p (1..20).map do |n| in Integer if n % 15 == 0 "fizzbuzz" in Integer if n % 3 == 0 "fizz" in Integer if n % 5 == 0 "buzz" in Integer n end
最初のコードを見たときは『どういうこっちゃ?』と思ったけどガード節と見れば納得した。
ただ、ガード節自体は便利だけど defined?
や call_or_else
は微妙なのでこれは別に議論すべきじゃないかなーと思わなくもない。
関係ないけど以下みたいなガード節書きたいよね?
class C def foo(*args) # 引数とパターンマッチして該当する処理を呼び出す in [Integer]; foo_int_body(a, nil) in [a]; foo_body(a, nil) in [a, b]; foo_body(a, b) end end