15

Perl は非常に甘美な言語であるため、世の中にはたくさんありますが、どの言語でも最もよく使用されるステートメントは、if ステートメントと設定値の組み合わせです。それらの多くを見つけたと思いますが、まだいくつかのギャップがあります。最終的には、変数名を複数回記述する必要がないようにすることが目標です。

これが私がこれまでに持っているものです:

$r ||= $s;          # $r = $s unless ($r);
$r //= $s;          # $r = $s unless (defined $r);
$r &&= $s;          # $r = $s if ($r);
$r = $c ? $s : $t;  # if ($c) { $r = $s } else { $r = $t }
$c ? $r : $s = $t;  # if ($c) { $r = $t } else { $s = $t }
$r = $s || $t;      # if ($s) { $r = $s } else { $r = $t }
$r = $s && $t;      # if ($s) { $r = $t } else { $r = $s = undef, 0, untrue, etc. }
$c and return $r;   # return $r if ($c);
$c or  return $r;   # return $r unless ($c);
$c and $r = $s;     # $r = $s if ($c);
@$r{qw(a b c d)}    # ($r->{a}, $r->{b}, $r->{c}, $r->{d})

「秘密のオペレーター」に関する非常に興味深い記事もありました。

my @part = (
    'http://example.net/app',
    ( 'admin'  ) x!! $is_admin_link,
    ( $subsite ) x!! defined $subsite,
    $mode,
    ( $id      ) x!! defined $id,
    ( $submode ) x!! defined $submode,
);

ただし、リストにないことがわかったのは次のとおりです。

$r <= $s;                 # read as "$r = min($r, $s);" except with short-circuiting
$r = $s if (defined $s);  # what's the opposite of //?
$r and return $r          # can that be done without repeating $r?

他に追加する価値のあるものはありますか?コードを削減するために利用できるその他の条件付きセット変数は何ですか? 他に何が欠けていますか?

4

5 に答える 5

8

andあなたの質問からのこれらの構造は、低い優先順位とorキーワードを使用してもう少し明確に書くことができます:

$c and return $r;    # return $r if ($c);
$c or return $r;     # return $r unless ($c);
$c and $r = $s;      # $r = $s if ($c);

andの良いところは、ステートメント修飾子の制御語とは異なり、and は複合and式に連鎖できることです。orandor

シンタックス シュガーのもう 1 つの便利なツールは、for/foreachループを単一の値に対するトピック化ツールとして使用することです。次の点を考慮してください。

$var = $new_value if defined $new_value;

defined and $var = $_ for $new_value;

または次のようなもの:

$foo = "[$foo]";
$bar = "[$bar]";

$_ = "[$_]" for $foo, $bar;

関数はこの方法でも使用でき、map使用できる戻り値があります。

于 2011-10-17T19:42:23.933 に答える
6

左辺の三項演算子もあります。

$cond ? $var1 : $var2 = "the value";

次と同等です。

if ($cond) {
    $var1 = "the value";
} else {
    $var2 = "the value";
}
于 2011-10-18T08:07:05.433 に答える
3

$r = $r < $s ? $r : $s;:

    $r = $s if $r > $s;

また

    use List::Util qw( min );

    $r = min($r, $s);

また:

    sub min_inplace {
       my $min_ref = \shift;
       for (@_) { $$min_ref = $_ if $$min_ref > $_; }
    }

    min_inplace($r, $s);

$r = $s if (defined $s);:

    $r = $s // $r;

$r = $t; $r = $s if (defined $s);:

    $r = $s // $t;

$r = !$s ? $s : $t;:

    $r = $s && $t;
于 2011-10-17T17:48:58.083 に答える
1

Perl で機能を求められた最大の機能の 1 つは、switchステートメントです。これは、Perl 5.10 でついに登場しました。ドキュメントの例を使用しているだけです:

use feature qw(say switch);  #My preference
#use feature ":5.10";        #This does both "say" and "switch"

[...]

given($foo) {
    when (undef) {
        say '$foo is undefined';
    }
    when ("foo") {
        say '$foo is the string "foo"';
    }
    when ([1,3,5,7,9]) {
        say '$foo is an odd digit';
        continue; # Fall through
    }
    when ($_ < 100) {
        say '$foo is numerically less than 100';
    }
    when (\&complicated_check) {
        say 'a complicated check for $foo is true';
    }
    default {
        die q(I don't know what to do with $foo);
    }
}

ほとんどの言語で見られるように、なぜ彼らが / を使って / を使わなかったのかは、givenwhenには謎です。そして、ステートメントが/の場合、なぜそれをasで指定するのですか?switchcasegivenwhenuse featuresswitch

悲しいかな、これらの決定を下した人々は私よりも高いレベルにいるので、私にはこれらの著名人に質問する権利さえありません.


私はよりエキゾチックなものを避け、最も理解しやすい構文に固執します。あなたのコードを調べて、機能追加のバグを見つけなければならない人を想像してみてください。

$r &&= $s;

また

if ($r) {
    $r = $s;
}

そして、たぶん、私が本当に意味していたことに気付くかもしれません:

if (not defined $r) {
    $r = $s;
}

そして、この場合、私は次のように言うかもしれません:

$r = $s if not defined $r;

ifコードをざっと見たときに人々がその部分を見逃す傾向があるため、私は通常、後置の if ステートメントは好きではありません。

Perl は実行時にコンパイルされ、コンパイラはかなり効率的です。そのため、書くのがずっとかっこよくなり、$r &&= $sより多くのオタク ポイントを獲得し、入力する必要が少なくなったとしても、実行速度が速くなるわけではありません。コードに費やされる最大の時間はコードの保守に費やされるため、凝ったものはスキップして読みやすさを重視します。

ところで、シンタックス シュガーというと、読みやすさを向上させるために言語に追加されたものを思い浮かべます。良い例は次の->演算子です。

${${${$employee_ref}[0]}{phone}}[0];

対。

$employee_ref->[0]->{phone}->[0];

もちろん、リストへのハッシュへのリストへの参照としてデータを格納している場合は、おそらくオブジェクト指向コーディングを使用した方がよいでしょう。

于 2011-10-17T17:15:10.780 に答える
0

次のものもあります。

$hash{$key||'foo'} = 1;  # if($key) { $hash{$key} = 1 } else { $hash{'foo'} = 1 }
于 2011-10-19T22:47:03.590 に答える