頭が回転しだして眠れなくなった。
メソッドチェーンしたいけど条件によってはしてほしくないときあるよね。
そういうときになぜだかあまり気が進まないやりかた:
condition = true
n = 0
n = n.next if condition
n = n.next if !condition
n
理由はわからないが気が進まないものは気が進まないので、他の方法を調べてみた。
.tap { break }
を使う
https://qiita.com/takeru@github/items/29f9cad9e2318b7e5b82
↑参考
condition = true
n = 0
n.tap { |x| break x.next if condition }.tap { |x| break x.next if condition }
# => 2
n.tap { |x| break x.next if condition }.tap { |x| break x.next if !condition }
# => 1
n.tap { |x| break x.next if !condition }.tap { |x| break x.next if condition }
# => 1
n.tap { |x| break x.next if !condition }.tap { |x| break x.next if condition }
# => 0
ハックっぽさが仕事では使いにくそう。
break しなければレシーバが引き継がれるのが良いところ。
try を使ってみる (rails)
https://stackoverflow.com/questions/33744368/conditionally-call-chained-method
↑の一番下の例。
try にブロックを渡せるのは知らなかった。
condition = true
n = 0
n.try { |x| condition ? x.next : x }.try { |x| condition ? x.next : x }
# => 2
n.try { |x| condition ? x.next : x }.try { |x| !condition ? x.next : x }
# => 1
n.try { |x| !condition ? x.next : x }.try { |x| condition ? x.next : x }
# => 1
n.try { |x| !condition ? x.next : x }.try { |x| !condition ? x.next : x }
# => 0
この try が何をしてるかというと引数がブロックのみだったら yield してるだけ。
レシーバは引き継がれないので返してやる必要がある。
配列に入れて inject (reduce)
https://stackoverflow.com/questions/1797189/conditional-chaining-in-ruby
↑の最初の例。
condition = ture
n = 0
l = []
l << :next if condition
l << :next if !condition
l << :next if condition
# l => [:next, :next]
l.inject(n) { |obj, method| obj.send(method) }
# => 2
引数を渡したければ配列で包んで渡してブロックの中でも使ってやれば良い。
l = []
l << [:method, arg1, arg2] if condition
ところで私は確信しておりますが、rubyist が好むのはこれじゃないでしょうか。