2010-10-25 17 views

Respuesta

14

Esos dos ejemplos equivalen a lo mismo conductualmente, pero consideran que si quería hacer algo más que después de la impresión de bloque:

print <<EOF 
stuff 
EOF 
. "more text here"; 

... o tal vez necesitan para poner a prueba el resultado de la operación:

print $unstable_filehandle <<EOF 
stuff 
EOF 
or warn "That filehandle finally disappeared: $!"; 

Estos ejemplos son artificiales, pero se puede ver cómo a veces puede ser útil para ser flexible en cuanto a qué código se produce después del bloque de texto.

2

Fwiw, Perl Best Practices recomienda:

print <<'EOF'; 
stuff 
EOF 
+1

No es lo mismo. Las comillas simples suprimen la interpolación. El equivalente de la pregunta sería con comillas dobles. – igelkott

+2

@igelkott: y pbp recomienda comillas simples donde no hay ninguna interpolación :) – ysth

+0

Sin embargo, no hay interpolación en el OP. –

4

Debe tratar heredoc tokens exactamente igual que las cadenas literales que son. No demore más puntuación o sintaxis hasta después de su contenido. Eso es engañoso y propenso a errores. He aquí diez ejemplos tomados de código real:

  1. ($is_a_valid_rfc_822_addr = <<'EOSCARY') =~ s/\n//g;
  2. $eval = (($Preamble=<<'END1') . $userstuff . <<'END2');
  3. for my $line (<<"End_of_Property_List" =~ m{ \S .* \S }gx) {
  4. $cases .= <<"EDQ" if $timeout;
  5. ($is_a_valid_rfc_822_addr = <<'EOSCARY') =~ s/\n//g;
  6. eval (($Preamble=<<'END1') . $_[0] . <<'END2');
  7. @changes = split("\n", <<"EOCHANGES");
  8. $change .= sprintf(<<"EOP", $in, $out, $in, $out);
  9. eval "{ package $package; " . <<'EOF' . "}";
  10. push @args, dequeue('|Q|', <<'END_OF_ASTRAL_MATCH') if $Opt{astral};

Ver cómo funciona?

9

Como tchrist señala, una cosa que la mayoría de la gente descuida es que el operador heredoc toma código de perl arbitrario después del código de terminación.

Esto significa que se puede hacer (posiblemente) la manipulación de aspecto más natural, como por ejemplo:

my $obj = Foo::Bar->new(content => <<EOP)->do_stuff->sprint(); 
    This is my content 
    It's from a heredoc. 
EOP 

Una consecuencia es que también se puede apilar ellos mucho más legible (en mi opinión;) que "no apiladas" :

-- stacked_heredoc.pl 
#!/usr/bin/perl 
use strict; 
use warnings; 

print join(<<JOINER, split("\n", <<SOURCE)); 

------------------------------ 
JOINER 
This is my text 
this is my other text 
a third line will get divided! 
SOURCE 

versos un heredoc unstacked ...

-- unstacked_heredoc.pl 
#!/usr/bin/perl 
use strict; 
use warnings; 

my $joiner = <<JOINER 

------------------------------ 
JOINER 
; 

my $source = <<SOURCE 
This is my text 
this is my other text 
a third line will get divided! 
SOURCE 
; 

print join($joiner, split("\n", $source)); 
1

Randal Schwartz tiene una gr comer artículo aquí documentos HERE.

hay varias cosas a tener en cuenta por aquí documentos:

  1. El ; en Perl es el terminador de sentencia y es necesario para todas las declaraciones de Perl (con algunas excepciones), incluyendo aquí las cadenas de documentos;
  2. El presente documento es una declaración de aspecto divertido que en realidad es solo una gran cadena;
  3. Debe haber un CR de terminación en un documento aquí (a diferencia de la mayoría de las demás sentencias de Perl);
  4. Puede tener un código de Perl arbitrario inmediatamente después de la etiqueta de apertura o después de la etiqueta de cierre. Si después de la etiqueta de cierre, debe estar en una línea separada. En cualquier caso, el código opera en el texto de la cadena aquí;
  5. Las comillas que usa en las etiquetas afectan a la cadena. Las comillas dobles son como cadenas de comillas dobles en Perl, las comillas simples no se interpolan, las comillas posteriores se pasan al shell. Sin citas son equivalentes a comillas dobles;
  6. TIMTOWTDI, pero algunas son formas difíciles de leer;
  7. citando de perldoc -q "HERE documents" (y perlfaq4):

    No debe haber ningún espacio después de la parte < <.

    Hay (probablemente) debe haber un punto y coma al final [de la parte <<].

    No puede (fácilmente) tener espacio en frente de la etiqueta.

Las dos formas que tiene son funcionalmente equivalentes. Al igual que { ... } if (blah blah) es lo mismo que if (blah blah) { ... }. Si bien estas dos afirmaciones son funcionalmente equivalentes, "leen" de manera diferente.

Cada uno de ellos es equivalente y válidos los documentos Perl aquí:

my %data = <<END 
fred: Fred Flintstone 
barney: Barney Rubble 
betty: Betty Rubble 
wilma: Wilma Flintstone 
END 
=~ /(\w+): (.*)/g; 

y

my %data = <<END =~ /(\w+): (.*)/g; 
fred: Fred Flintstone 
barney: Barney Rubble 
betty: Betty Rubble 
wilma: Wilma Flintstone 
END 

# You must have a CR after the "END". Can't be EOF... 

ambos conjuntos el hash %data-first=>"full name" de los Picapiedra. ¿Qué prefieres ver en el código que viene a ti?

Nota a la segunda forma es uno donde hay una Gotcha: Es necesario que haya texto o un espacio en blanco después de la marca de terminación o pueden producirse Can't find string terminator "END" anywhere before EOF Creo que es por eso que se ve el solitario ; en algunas de las personas aquí docs.

En mi humilde opinión, el ; pertenece después de la primera instancia de la etiqueta aquí doc o el código que lo sigue. Es más difícil de leer si está después de la etiqueta de cierre. A menos que, la etiqueta de cierre está en una forma similar a un modificador de sentencia o una lógica de advertencia o muerte. Esa es solo mi guía de estilo personal.

Cuestiones relacionadas