Memoize |
BasicWerk
EC Support
Technique
Facebook
|
20140902181358_Ruby_if |
Ruby_if
Ruby では if が値を返すので、こんな書き方が出来る。 x = 0 if x calc = lambda {|n| n + x} else calc = lambda {|n| n} end # => #<Proc:0x007fd35a06c338@(pry):3 (lambda)> # lambda ブロックが返され、更に calc にバインドされた状態で参照できる (-3..10).map(&calc) # => [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] x = 8 (-3..10).map(&calc) # => [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18] x = nil (-3..10).map(&calc) # => [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
だから calc はこう書いたのと同等だ。 x = nil # ここで calc を宣言(してもしなくてもよいということ) calc = nil if x calc = lambda {|n| n + x} else calc = lambda {|n| n} end # => #<Proc:0x007fd35a4aa3a0@(pry):38 (lambda)> (-3..10).map(&calc) # => [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
分岐によって lambda の中身が複雑になったり、多大なオーバーヘッドが発生するようなら、 最初から lambda オブジェクトを「作り分ける」というやり方は good だと思う。
でも個人的にはなるべくこう書くのが好きだ。 (この例なら、if で分岐させる為の計算量が無視できる程度のオーバーヘッドなら、という前提だが。) x = 99 calc = lambda do |n| if x then n + x else n end end # => #<Proc:0x007fd35c09a560@(pry):43 (lambda)> (-3..10).map(&calc) # => [96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
|
© Shin Nakamura/BasicWerk 2014 |