Value-Based Error Handling Mechanisms
追記 2024-03-07
OTP-27.0-RC1 がリリースされ maybe を利用する場合には特に設定が不要になりました
追記 2023-03-31
OTP-26.0-RC2 がリリースされ maybe を利用する場合は -feature(maybe_expr, enable).
を指定することをオススメします。
OTP-27.0 で maybe は何も指定せずに利用できるようになります。
追記 2022-02-21
OTP-25.0-RC1 がリリースされ maybe が利用可能になりました。利用するには {enable_feature, maybe_expr}
を有効にする必要があります。
commit_write(OpaqueData) ->
maybe
ok ?= disk_log:sync(OpaqueData#backup.file_desc),
ok ?= disk_log:close(OpaqueData#backup.file_desc),
ok ?= file:rename(OpaqueData#backup.tmp_file, OpaqueData#backup.file),
{ok, OpaqueData#backup.file}
else
error ->
{error, invalid_write};
{error, Reason} ->
{error, Reason}
end.
追記 2021-11-17
<~
から ?=
に変更されました。
仕様が確定し、最終実装のドラフトがでました。
Implement EEP 49 (Value-Based Error Handling Mechanisms) by bjorng · Pull Request #5405 · erlang/otp
上記 PR をビルド、その後 BRAM ビルド時のコンパイルオプションに {enable_feature, maybe_expr}
を指定することで、 maybe 構文が利用できるようになった。
追記 2021-11-03
リスト/バイナリ内包表記で利用されている <-
を使うのはやめて、 <-
から <~
に変更されました。
Update eep-0049 with decisions from OTP Technical Board by bjorng · Pull Request #35 · erlang/eep
それを踏まえた OTP チームからの実装が出てきました。
Implement the compiler part of EEP 49 by bjorng · Pull Request #5340 · erlang/otp
本編
maybe ... end
構文の提案が進められています。
Erlang は素敵な文法ではないため case ... of
だとネストの嵐になります。
commit_write(OpaqueData) ->
B = OpaqueData,
case disk_log:sync(B#backup.file_desc) of
ok ->
case disk_log:close(B#backup.file_desc) of
ok ->
case file:rename(B#backup.tmp_file, B#backup.file) of
ok ->
{ok, B#backup.file};
{error, Reason} ->
{error, Reason}
end;
{error, Reason} ->
{error, Reason}
end;
{error, Reason} ->
{error, Reason}
end.
これが以下のように書けるようになります。
commit_write(OpaqueData) ->
maybe
ok ?= disk_log:sync(OpaqueData#backup.file_desc),
ok ?= disk_log:close(OpaqueData#backup.file_desc),
ok ?= file:rename(OpaqueData#backup.tmp_file, OpaqueData#backup.file),
{ok, OpaqueData#backup.file}
end.
commit_write(OpaqueData) ->
maybe
ok ?= disk_log:sync(OpaqueData#backup.file_desc),
ok ?= disk_log:close(OpaqueData#backup.file_desc),
ok ?= file:rename(OpaqueData#backup.tmp_file, OpaqueData#backup.file),
{ok, OpaqueData#backup.file}
else
{error, Reason} -> {error, Reason}
end.
提案は EEP 49: Value-Based Error Handling Mechanisms で確認することができます。しっかりと書かれているので、一読する価値はあります。
そして実装については EEP-49: First proof of concept implementation by ferd · Pull Request #5216 · erlang/otp で確認することが可能です。
おまけとして parse_transform を利用して同じような仕組みを実現していた rabbitmq/erlando: Erlando があります。これ以前、使っていたんですが凄く便利でした。
何にせよ、可読性は高くなりつつも、綺麗に書けるようになる文法提案だと思っています。OTP-25 への導入に向けて進めているようなので、とても楽しみです。
Discussion