subrutina llamar for contiene perl while-loop

llamar - Perl: mientras que sin condicional



llamar subrutina perl (3)

De acuerdo con el doc , la instrucción while ejecuta el bloque siempre que la expresión sea true . Me pregunto por qué se convierte en un ciclo infinito con una expresión vacía:

while () { # infinite loop ... }

¿Es solo inexactitud en el documento?


Este es un caso especial del concepto de verdad vacua . Si no hay una condición, la declaración mientras la condición es verdadera es en sí misma vacuamente cierta.

Si estoy leyendo esto correctamente, la pieza relevante de código parece estar alrededor de la línea 5853 de op.c en 5.14.1:

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;

o = listop sin expr en la condición, alcanzamos o = listop . listop se definió previamente como listop = op_append_list(OP_LINESEQ, block, cont); .


Este es un caso especial. Una expresión de condición vacía se establece de manera predeterminada como true , lo que significa "ciclo para siempre, o hasta un break . En C (y perl) la expresión idiomática

for(;;) { // Neverending fun }

tiene el mismo efecto por la misma razón.

No parece haber ninguna mención de esto en los documentos oficiales de Perl, y sin embargo, hay una regla especial en el analizador sintáctico. Tal vez es porque nadie lo usa :)

La expresión for(;;) es menos común.


$ perl -MO=Deparse -e ''while () { }'' while (1) { (); } -e syntax OK

Parece que while () {} y while (1) {} son equivalentes. También tenga en cuenta que los paréntesis vacíos * se insertan en el bloque vacío.

Otro ejemplo de comportamiento del compilador predefinido:

$ perl -MO=Deparse -e ''while (<>) { }'' while (defined($_ = <ARGV>)) { (); } -e syntax OK

Yo diría que esto es solo los documentos que no informan un caso especial.

* - Para ser precisos, se inserta el stub operación stub . No hace nada, pero sirve un objetivo goto para el enterloop operación enterloop . No hay una razón real para notar esto. Deparse denota este stub op usando parens vacíos, ya que los pares no generan código.