日々常々

ふつうのプログラマがあたりまえにしたいこと。

公式ドキュメントを読めというけど

公式ドキュメントだからと言って、考えなしにそのコードを切り貼りしてはいけないんです。 っていう私の失敗談。露悪趣味はありません。

Javaの公式ドキュメントとしてJSLAPI仕様(Javadocと呼ばれたりする)があります。 コード例が載ってると「挙動理解するためにとりあえず実行してみようか」とやったりします。

その対象になったのがこのコード。

https://docs.oracle.com/javase/jp/8/docs/api/java/nio/file/FileVisitor.html

Path start = ...
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
   @Override
   public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
       throws IOException
   {
       Files.delete(file);
       return FileVisitResult.CONTINUE;
   }
   @Override
   public FileVisitResult postVisitDirectory(Path dir, IOException e)
       throws IOException
   {
       if (e == null) {
           Files.delete(dir);
           return FileVisitResult.CONTINUE;
       } else {
           // directory iteration failed
           throw e;
       }
   }
});

簡単に言えば rm -rf {指定したパス} です。なにそれこわい。

コードを読みさえすれば実行したら危ないのはわかるかなとは思うんですが、そういう危なさが判りづらいのがJavaの冗長と言われる所以だと思います。 仮にこれを今の自分が実装するなら、deleteがもっと目立つようにするんじゃないかな。ツリーを辿るっていうのと実行する操作は別の関心だと思うし。

教訓としては「公式ドキュメントかどうかに関わらず、コードをコピペで迂闊に試してはいけない」です。 ファイル削除だからまだいいけど、どっかにファイル送信するとかだったらえらいことです。流石にそんなコードはまともなドキュメントにはないだろうけど、どこぞのブログとかだったらあっても不思議じゃない。

当時のツイート

f:id:irof:20211108143118p:plain

10年も前の話です。今でも思い出せる程度にはショッキングな出来事でした。Java7リリースは2011-07-28なので、リリース前ですね。 人間は失敗して成長するんですよ。失敗したからと言って成長するとは限らないけど。

f:id:irof:20211108180430p:plain

どうにもならなかったから諦めた(諦められたという意味でどうにかはなってるのだけど)。

ついでに新しい話

そういえばJava 18でJavadocコードスニペットが入ります。 JEP 413: Code Snippets in Java API Documentation です。 {@code} とかは既にありますが、導入の動機となる現在の問題はJEPを参照ください。