無名インナークラス
1つのメソッド内で、数行で見渡せるように。というか、リソースのopen/closeは1箇所にまとめるようにしたいけど、それはどこまでできるかな。
ちょっと考えてみました。
Rubyにはブロックがある
Rubyのopenメソッドにはブロックを渡すと自動的にcloseしてくれる機能があるんですって
open('hoge.txt'){|f|f.each{|l|puts l}}
むりやり一行で書いたけど、なんだかよくわからないので do 〜 end で書き直し
File.open('hoge.txt') do |file| file.each do |line| puts line end end
open関数の内部でブロックを実行した後、確実にcloseを呼んでくれるのだそうです。これは嬉しい。
Javaにはブロックがない
でもそのかわり、無名インナークラスっていうものがあるので、それをつかってブロックの真似事をしてみたらこんな感じになりました。
public class Main { public static void main( String[] args ) throws Exception { // open/close は全部Hogeに任せて、openとcloseの間に入る処理を // Blockインターフェースを実装したインナークラスとして渡す。 Hoge.read( "hoge.txt", new Block() { public void execute( FileInputStream stream ) throws Exception { // なんか処理をする。 // 外側にある変数も見えるよ。( final変数に限る ) } }); } }
class Hoge { public static void read( String name, Block block ) { FileInputStream stream = null; // ファイルを開くよ try { stream = new FileInputStream( name ); } catch (FileNotFoundException e) { throw new RuntimeException( e ); } try { // ブロックを実行する。 block.execute( stream ); } catch (Exception e) { throw new RuntimeException( e ); } finally { // 開けた人が閉じる try { stream.close(); } catch (IOException e) { throw new RuntimeException( e ); } } } } interface Block { public abstract void execute( FileInputStream stream ) throws Exception ; }
無名インナークラスを使うと、ネストが深くなってソースが汚くなるし、「Main$1.class」みたいなクラスファイルができるので納品のときに「ソースファイルとクラスファイルの数が合わないじゃないか」と文句言われたりするし、「い」が2回続くので発音しづらいしで、とにかく人気のない可哀想なヤツっていうイメージがあります。
でも、openとcloseの部分だけを完全に隠せるのは便利だと思いました。