Proc.newで冗長なコードを取りまとめ
「cp」と「mv」とメソッド名が2文字しか違わない以下の冗長なコードをまとめる方法として、Procオブジェクトを使ってみることにした。
if Options[:copy] Options[:events].each {|n| nikon.event(n).each {|photo| FileUtils.cp(photo[0],".", {:verbose => Options[:verbose]}) } } elsif Options[:move] Options[:events].each {|n| nikon.event(n).each {|photo| FileUtils.mv(photo[0],".", {:verbose => Options[:verbose]}) } }
if Options[:copy] f = Proc.new {|src,dest,opt| FileUtils.cp(src,dest,opt)} elsif Options[:move] f = Proc.new {|src,dest,opt| FileUtils.mv(src,dest,opt)} else :(省略) end if f.class == Proc Options[:events].each {|n| nikon.event(n).each {|photo| f.call(photo[0],".", {:verbose => Options[:verbose]}) } } end
もっとすっきりするかと思ったけど、結局、重複感は残る。まあ、Procオブジェクトというのがあって、どうも関数オブジェクトとして扱えるらしいということが分かったのでよしとする。
と、思ったけど、別のやり方で、また変えてみた。
if Options[:copy] || Options[:move] f = Proc.new {|src,dest,opt| case when Options[:copy] FileUtils.cp(src,dest,opt) when Options[:move] FileUtils.mv(src,dest,opt) end } Options[:events].each {|n| nikon.event(n).each {|photo| f.call(photo[0],".", {:verbose => Options[:verbose]}) } } else (省略)
うーん、あんまり変わらない。でも、制御構造の中で関数をスイッチしてfに代入しているこの方法のほうが、なんか処理の本質に近い気がする。