今日はProcを使って文字列を作ります。
> b = proc {|x, y, z| "%s %s %s" % [(x||"0"),(y||"0"),(z||"0")] } => #<Proc:0x007fb063c00dd0@(irb):10> > b.("as","you","like") => "as you like" > b.("as","you") => "as you 0"
これがlambdaだと、引数チェックが厳密なので上手く行きません。
> b = lambda {|x, y, z| "%s %s %s" % [(x||"0"),(y||"0"),(z||"0")] } => #<Proc:0x007fb063bee720@(irb):13 (lambda)> > b.("as","you") ArgumentError: wrong number of arguments (2 for 3) from (irb):13:in `block in irb_binding' from (irb):14:in `call' from (irb):14 from /Users/shuzo/.rbenv/versions/1.9.3-p448/bin/irb:12:in `<main>'
変数がバラつくようなら、ブロックの引数を工夫してあげればどちらでも行けます。
> proc {|*a| "%s %s %s" % [(a[0]||"0"),(a[1]||"0"),(a[2]||"0")] }.call("1","2") => "1 2 0" > lambda {|*a| "%s %s %s" % [(a[0]||"0"),(a[1]||"0"),(a[2]||"0")] }.call("1","2") => "1 2 0"
何が何でも一行で収めたい場合はcallを使います。
proc {|x, y, z| "%s %s %s" % [(x||"0"),(y||"0"),(z||"0")] }.call(nil, "you", Time.now) => "0 you 2013-11-10 20:56:49 +0900"
とできます。
結果をを文字列として取得したい場合は、
> b = Proc.new {|x, y, z| "%s %s %s" % [(x||"0"),(y||"0"),(z||"0")] } => #<Proc:0x007fb063b72d78@(irb):23> > str = b.("as", "you", "like") => "as you like"
いかがでしたか?
procを使えばワンライナーでも鬼のように入り組んだ文字列だって楽に作れます。