ネストが深くなると嘆く前に

goto文を使いましょう(笑

や、冗談抜きで、lastとかnextとか、言語によってはbreakだったりcontinueだったりしますが、この手の実質goto文をいかにうまく使うかってもコードの可読性を高めるポイントのひとつなんでないかなと。

ふたつ下の例でもif文のネストを減らすのにブロックとlastを使っていますが、Basic(On Error GoTo ...)がいみじくも明示しているように、エラー/例外処理ってのはどうやったってどこかへ飛ばないと始まらない。や、if文の条件処理だって同じですやね。内部的にはelseやelsifのところまで飛んでいるはずですよ。

fbisさんがいわゆるswitch文をif 〜 elsif 〜 else 〜で実装してますが、こんなのも

sub func {
  my ($param) = @_;
  my $ret; # 戻り値用の変数

SWITCH:
  {
    if (!@_)               { $ret = undef; last; }
    if (!defined $param)   { $ret = 0;     last; }
    if ($param !~ /^\d+$/) { $ret = 0;     last; }
    if ($param > 10000)    { $ret = 0;     last; }
    if ($param == 0)       { $ret = 1;     last; }
    if ($param % 2 == 0)   { $ret = 2;     last; }
    if ($param % 2 == 1)   { $ret = 3;     last; }
  }

  return $ret;
}

とでもすれば出口ひとつで済む話。

もちろんいちいちlastせんで直接returnしたっていいし、ifを後置できるPerl5的にはその方がきれいだと思いますが、短い区間のgotoはもっと積極的に使っていいと思うし、gotoの距離が長くなりすぎるようなら途中をサブルーチン化(抽象化)することを考えた方がいいかもしらんのじゃないかな、と。

ま、これもまたTMTOWTDIということで。