doc によると、式が true である限り、while
ステートメントはブロックを実行します。空の式で無限ループになるのはなぜでしょうか。
while () { # infinite loop
...
}
それは単にドキュメントが不正確なのですか?
_$ Perl -MO=Deparse -e 'while () { }'
while (1) {
();
}
-e syntax OK
_
while () {}
とwhile (1) {}
は同等のようです。また、空の括弧*が空のブロックに挿入されることに注意してください。
事前定義されたコンパイラの動作の別の例:
_$ Perl -MO=Deparse -e 'while (<>) { }'
while (defined($_ = <ARGV>)) {
();
}
-e syntax OK
_
これは、特別なケースを報告していないドキュメントにすぎないと思います。
* —正確には、stub
オペコードが挿入されます。何もしませんが、enterloop
オペコードのgotoターゲットを提供します。これに注意する本当の理由はありません。括弧はコードを生成しないため、Deparseは空の括弧を使用してこのstub
opを示します。
これは Vacuous Truth の概念の特別なケースです。条件がない場合、ステートメントがである一方で、条件がtrueであると、それ自体が空虚にtrueになります。
これを正しく読んでいる場合、関連するコードは 5.14.1の_op.c
_ の5853行目です:
_5853 if (expr) {
5854 scalar(listop);
5855 o = new_logop(OP_AND, 0, &expr, &listop);
5856 if (o == expr && o->op_type == OP_CONST && !SvTRUE(cSVOPo->op_sv)) {
5857 op_free(expr); /* oops, it's a while (0) */
5858 op_free((OP*)loop);
5859 return NULL; /* listop already freed by new_logop */
5860 }
5861 if (listop)
5862 ((LISTOP*)listop)->op_last->op_next =
5863 (o == listop ? redo : LINKLIST(o));
5864 }
5865 else
5866 o = listop;
_
条件にexpr
がないと仮定すると、_o = listop
_に到達します。 listop
は、以前はlistop = op_append_list(OP_LINESEQ, block, cont);
として定義されていました。
これは特殊なケースです。空の条件式は、デフォルトでtrue
のみに設定されます。これは、「永久にループするか、またはbreak
までループすることを意味します。C(およびPerl)では、イディオム
_for(;;) {
// Neverending fun
}
_
同じ理由で同じ効果があります。
公式のPerlドキュメントにはこれについての言及はないようですが、パーサーにはそのための特別なルールがあります。多分それはだれもそれを使用していないからです:)
for(;;)
イディオムはそれほど珍しくありません。