mike-neckのブログ

JavaかJavaFXかJavaEE(なんかJava8が多め)

try-with-resources に複数のリソースを指定した場合の close の実行順

年末年始に書いていたコードで気になったことがあったので調べた。

f:id:mike_neck:20181019112748p:plain

結論だけ先に書くと、 try-with-resources に選択したリソースの順番の逆順になる。


Java9 以降で使えるようになった effevtively-final variables in try-with-resources の実行順がどうなるのかちゃんと理解していなかったが、 Java 言語仕様には書かれていた。

引用すると次の箇所

Resources are initialized in left-to-right order. ...

リソースは左から右の順番に初期化される

Resources are closed in the reverse order from that in which they were initialized. ... An exception from the closing of one resource does not prevent the closing of other resources.

リソースは初期化とは逆順にクローズされる。クローズ時に例外が発生した場合でも他のリソースのクローズに支障をきたさない

ここで、初期化すでにしているのではないかと思うのだが、続く 14.20.3.1 を読んで try-with-resources スコープの中での初期化のことなのかと思ったのだが誤解しているかもしれない。

14.20.3.1 の内容を一部だけ書くと、

try (autoCloseable) {

}

となっていたものは、一度次のような形に変換されるらしい。

try (final T resource = autoCloseable) {

}

というわけで、次のコードを jshell で動かして実験する。

try にて指定するリソースに 0 からの順番に名前をつける。一方、クローズする順番を 0 から数えていく。また、 4 番目(名前は 3)のリソースのクローズ時に例外を発生させる

この時に、仕様通りであれば、

int[] count = new int[] { 0 };

AutoCloseable autoCloseable(int num) {
  return () -> {
    System.out.println("num: " + num + " -> " + count[0]++);
    if (num % 4 == 3) {
      throw new Exception("num: " + num);
    }
  };
}

try {
  final AutoCloseable a0 = autoCloseable(0);
  final AutoCloseable a1 = autoCloseable(1);
  final AutoCloseable a2 = autoCloseable(2);
  final AutoCloseable a3 = autoCloseable(3);
  final AutoCloseable a4 = autoCloseable(4);
  try (a0; a1; a2; a3; a4) {
    System.out.println("action in try");
  } catch (final Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
} catch (final Exception e) {
  System.out.println("outer: " + e.getMessage());
} finally {
  System.out.println("finish");
}

これの出力結果は次のとおりとなった。

action in try
num: 4 -> 0
num: 3 -> 1
num: 2 -> 2
num: 1 -> 3
num: 0 -> 4
num: 3
outer: num: 3
finish

結論

try(r0;r1;r2 ...) と複数のリソースを指定した場合のクローズ実行順は逆順、つまり r2, r1, r0 の順番になる

合同勉強会 in 大都会岡山 にて 『Vim 入門』というタイトルで LT してきました #gbdaitokai

f:id:mike_neck:20181208195209p:plain
Vim 入門

2018/12/22 開催された 合同勉強会 in 大都会岡山 にて『Vim 入門』というタイトルで LT をしてきました。

gbdaitokai.connpass.com

どうやら評判がよかったのか、 LT 枠での表彰は当初予定になかったようでしたが、審査員特別賞なるものをいただきました。


特別賞を頂いた LT の資料はこちらです。

www.slideshare.net

なお、詳細な内容は以前の記事に書いたとおりです。

mike-neck.hatenadiary.com

また、デモで使ったスクリプト等はこちらより入手可能です(ただし、 デモ中にちゃんとあげたやつですよという証跡が欲しかったので、 CodePipeline / CloudFormation でデプロイするようにしてあります。あと、 readme をメンテし忘れています)

github.com

また、僕の LT に対する反応は以下のまとめの 16 〜 17 ページあたりにまとめられています。

togetter.com


今回の LT は非常に良い反応を得られるできの良さでしたが、多分まぐれなので何が良かったのか反省しておきたいと思います。

Swift 用の正規表現ライブラリー

これは Qiita のアドベントカレンダー2018 の19日目のエントリーです。

qiita.com

Swift の勉強を始めたのが今年の5月末からで、約半年程度 Swift をやってきました。ただ、僕は仕事では一切 Swift を書いていないので、知見に溢れた他の方のエントリーを楽しみにしています(突然の煽り)。

f:id:mike_neck:20180609045321p:plain


Swift を勉強し始めて3ヶ月くらいの頃に、ふとしたきっかけで正規表現が欲しくなりました。調べてみたところどうやら Swift 単体で使える正規表現がなく、 NSRegularExpression を使って、結構面倒そうなコードを書くらしいということがわかりました。しかし、これが Linux で使えるのかわからない(実際には使える)ので、その時は正規表現を使わない方法でとりあえず回避しました。

また、後日、詳しそうな人に尋ねたところ、 NSRegularExpression をラップして String などの extension とするライブラリーを自作しているとのことでした。 実際、 GitHub で 「 Swift regex 」 で調べてみると、そのようなライブラリーがたくさんあるようです。


というわけで、そのようなライブラリーを使えばよいのですが、 Swift の勉強がてら正規表現ライブラリーを作ってみるのも面白そうだと思い、作ってみることにしました。レポジトリーはこちらです。

github.com


仕組み

仕組みはいたって簡単で、 C 言語の正規表現ライブラリーをラップしているだけです。今のところ POSIX正規表現(regex.h)をラップしたもののみを提供しています。Swift から C 言語を呼び出す方法等は過去にエントリーを書いているので、そちらを見ると良いと思います。

mike-neck.hatenadiary.com

mike-neck.hatenadiary.com


導入方法

Swift Package Manager を使います。残念ながらその他のビルドシステムの方法は知らないので、PRくれるとノールックでマージすると思います。

次の依存ライブラリーを追加します。

  dependencies [
    .package(url: "https://github.com/mike-neck/swift-regex.git", from: "0.1"),
  ]

ターゲットに加えます。

targets [
    .target(name: "YourAwesomeApp", dependencies: [
        "SwiftRegex",
        "POSIXRegex",
    ]),
]

このライブラリーには今のところ3つモジュールがあります。

  • SwiftRegex - API を定めているモジュール
  • POSIXRegex - APIPOSIX 実装モジュールで、次の CPOSIXRegex モジュールをラップしています
  • CPOSIXRegex - POSIX正規表現を呼び出す C で書かれたモジュール

これらのうち、 API と 実装モジュールをターゲットに加えれば、このライブラリーを利用できます。


コード例

import POSIXRegex
import SwiftRegex

SwiftRegexImplementation.by.usePosix() // 1

guard let regex = pattern(of: "ba").compile() else { // 2
    fatalError { "cannot compile pattern \"ba\"" }
} 

let matcher = regex.matcher(for: "foo-bar-baz") //3
matcher.matches // -> true //4
  1. SwiftRegexSwiftRegexImplementation という長ったらしい名前の構造体があり、それの static プロパティ byusePosix() という関数が生えているので、これを呼び出すと、 POSIX 実装の正規表現が使えます。
  2. pattern(of:) という関数があるので、それを呼び出してからコンパイルします。コンパイルの結果は SwiftRegex? となっており、正規表現が間違えているなどコンパイルできない場合は nil が返ってきます。
  3. 検索ソースの文字列を matcher(for:) 関数にわたすと検索結果が返ってきます
  4. 今のところ matches プロパティで検索結果だけが取り出せるようになっています。(今後、置換を実装していこうと思っています)

という感じのライブラリーですが、どうやら Swift5 以降に正規表現が加わるかもしれないそうなので短命に終わるかもしれないです。「へぇ〜」と思ったそこのアナタ!、ぜひGitHubでスターを付けてってください!【2018/12/19 15:45 間違えているので修正しました】

JJUG CCC 2018 (Winterでなく)Fall に参加してきた

表記の通り、 JJUG CCC 2018 (もう 12 月だけど) Fall に参加してきた

www.java-users.jp

で、恒例のそのメモ

f:id:mike_neck:20181019112748p:plain


Pivotal認定講師によるSpring Framework 5.1ハンズオン!

日本で唯一の Pivotal 認定講師カサレアルの 多田さん とカサレアルのスタッフによる Spring Framework 5.1 のハンズオン。 (【2018/12/17 9:08 追記】後ほど教えてもらった話によると、正確には多田さんは Spring Cloud と Cloud Foundry の唯一の認定講師で、 Spring の認定講師には 土岐さんもいらっしゃるとのこと)

教材がかなり作り込まれており、ひょっとしたら、カサレアルで行っている研修内容に近いのではないかと思えるくらいクオリティの高いハンズオンでした(カサレアルのページによると、 『はじめての Spring Mvc によるシステム開発』 というコースで 10 万円だそうで、このセッションに参加するだけで5万円くらいはとってもよさそうなくらいのクオリティ)。

また、多田さんは日本で唯一の Pivotal 認定講師ですが、その一方で、「アブストラクアノテーションコンフィグディスパッチャーサーブレットイニシャライザー」を早口で舌を噛まずに言える日本人唯一の人なので、それを聞くためにも参加して損はしないハンズオンでした。

参加した意図は Spring にここ最近触れていないので、感覚を取り戻しておきたかったからです。ほとんど変わっていないことは確認できる一方、 @RepositoryCrudRepository につけなくてもよくなっていたりで、より簡略できるようになっていることが確認できました。

あとどうでも良い話ですが、前日に準備してくださいと言われていたので、準備した際に、宗教的な理由により maven で構築されたプロジェクトを gradle に移行して本セッションに臨みました。


思考停止しないアーキテクチャー設計

無職を辞めて最近会社を作った 川島さん のセッション。昼休みから戻った時点で部屋が6〜7割埋まってしまうほどの大人気セッションでした。

雑にまとめた内容

  • 非機能要件からアーキテクチャーを決定していく
  • ただし機能要件からもアーキテクチャー要求が発生することがある
  • どんなに丁寧にやってもアーキテクチャー設計の考慮漏れを防ぐのは難しい
  • 企画した後に前提が変わることもあり、技術的負債のメモ/金額換算をしておいて、リスク等を低減する

なお、冒頭に会社設立のゲーム化したもののデモプレイが流れました。 URL を取り忘れたので、誰かあとで教えてください。

(【2018/12/17 9:08 追記】起業クエスト はこちら → 起業クエスト tada_suzu さん ありがとうございます)


複雑なドメインに泥臭く立ち向かう

Koji Sudoさんによる 複雑な業務をどのようにモデル化して、実装に落とし込むかの理論的な話と実際の取り組み例を紹介するセッションでした。すごく話し上手で、聞いているだけで自分があたかもデキる人に感じてしまう魅惑なセッションでもあります。

以下雑なまとめ

  • アプリケーションの最も実現したい部分をまず作ってから、複合的なパターンを構築していく
    • 複雑なものを最初からすべて実現するように作ると、複雑で読解困難なものができてしまう
  • 複雑な業務をモデル化するために
    • 業務について書かれている書籍やガイドなどをもとに勉強する
    • 業務を実際に体験する(ロールプレイングする)
  • モデルを抽出するのは、複雑なものを簡単にするためではなく、複雑なものを人間が理解できるようにするため
  • 複数人で開発する場合、分野により個々の力量差があるため、モブプログラミングを採用するなどして複数のプログラムにレベルの差が現れないようにする
  • データと情報を区別する
    • データ : クラスを構成する値など
    • 情報 : データから導き出される値など

次の時間は眠気で休んでいました

しかし、久保田さんのセッションと思しきツイートがいくつか見られました。自分の勤務先でも現在 Java8 から Java 11 への移行を計画していますが、一度フレームワーク/ライブラリー等の移行のための動作確認等を行っておいたほうがよいかと思いました。


コードをど真ん中にそえた設計アプローチ

いろふさん のセッション。上級者向けとあり、世の中の Java 上級エンジニアが大挙して集まるセッションでした。内容はコードとドキュメントと設計をどのようにして楽におこなうかという話。

以下雑なまとめ

  • ドキュメントは基本的にメンテされないので、動くコードから生成する
  • ロジックよりは型に意図を込めていく
  • ドキュメントとするためにコードが歪むのは本末転倒

また、 JIG というライブラリーを作っていて、こちらからドキュメントを生成するような仕組みを作っているとのことです。

github.com


アンカンファレンス「OSSとコミュニティの運営など」

本当は 「GCを発生させないJVMとコーディングスタイル」 を見ようと思っていたのですが、長蛇の列を見て諦めました。で、とりあえず入ったのがこのセッション。

  • OSS のフリーライド等
    • US の企業で OSS を無償(ノーサポート)で使っていてそのトラブルに見舞われて解決できない場合などは、その企業は株主にかなり責め立てられるそうです(当然、株は売られるので株価が下がる)。したがって、 OSS を使う場合にお金を払うのは企業の姿として至極当然のようです(Red Hat はこのあたりをビジネスにしている)。
  • Meetup のドタキャン
    • 日本だけの問題でもないとのこと
    • わりと企業が Meetup のスポンサーになるそうで、懇親会をしてから本編をやるなどの工夫があるようです

懇親会

本来は懇親会に参加の予定はなかったのですが、 Java チャンピオンの せろさん の機転により参加できました。


今回振り返ってみてですが、あまり先進的なトピックのセッションではなく、開発プロセスの話を多く聞いたように思います。開発プロセスの話に面白そうなのが多かったというのが理由です。