В чем разница между этими двумя фрагментами Perl? - PullRequest
7 голосов
/ 25 октября 2010
print <<EOF
stuff
EOF
;


print <<EOF;
stuff
EOF

Зачем вам использовать один над другим?

Ответы [ 5 ]

14 голосов
/ 25 октября 2010

Эти два примера представляют собой одно и то же поведение поведенчески, но подумайте, хотите ли вы сделать что-то еще после печати этого блока:

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

... или, возможно, вам нужно проверить результат операции:

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

Эти примеры надуманы, но вы можете видеть, как иногда полезно быть гибким в отношении того, какой код следует за блоком текста.

9 голосов
/ 25 октября 2010

Как указывает tchrist, большинство людей пренебрегают тем, что оператор heredoc получает произвольный код perl после кода завершения.

Это означает, что вы можете (возможно) сделать большеестественно выглядящие манипуляции, такие как:

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

Одним из следствий этого является то, что вы также можете сложить их НАМНОГО более читабельно (на мой взгляд;), чем "unstacked":

-- 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

стихне собранные в наследство ...

-- 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));
4 голосов
/ 25 октября 2010

Вы должны обращаться с токенами heredoc точно так же, как и с строковыми литералами. Не откладывайте дальнейшую пунктуацию или синтаксис до окончания их содержания. Это вводит в заблуждение и подвержено ошибкам. Вот десять примеров, взятых из реального кода:

  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};

Видите, как это работает?

2 голосов
/ 25 октября 2010

FWIW, Perl Best Practices рекомендует:

print <<'EOF';
stuff
EOF
1 голос
/ 26 октября 2010

У Рэндала Шварца есть отличная статья о документах ЗДЕСЬ .

Есть несколько вещей, которые следует помнить об этих документах:

  1. ; в Perl является терминатором оператора и требуется для всех операторов Perl (с некоторыми исключениями), включая здесь строки документов;
  2. Этот документ представляет собой забавное выражение, которое на самом деле представляет собой большую строку;
  3. Должен быть завершающий CR для документа здесь (в отличие от большинства других операторов Perl);
  4. Вы можете иметь произвольный код Perl сразу после открывающего тега или после закрывающего тега. Если после закрывающего тега он должен находиться на отдельной строке. В любом случае код работает с текстом строки here;
  5. Кавычки, которые вы используете в тегах, влияют на строку. Двойные кавычки похожи на строки двойных кавычек в Perl, одинарные кавычки не интерполируются, обратные кавычки передаются в оболочку. Никакие кавычки не эквивалентны двойным кавычкам;
  6. TIMTOWTDI, но некоторые формы трудно читать;
  7. Цитирование из perldoc -q "HERE documents" perlfaq4 ):

    После << part. Пробела не должно быть. </strong>

    (вероятно) должна быть точка с запятой в конце [<< части].

    Вы не можете (легко) иметь пробел перед тегом.

Две ваши формы функционально эквивалентны. Так же, как { ... } if (blah blah) совпадает с if (blah blah) { ... }. Хотя эти два утверждения функционально эквивалентны, они «читают» по-разному.

Каждый из них является эквивалентным и действующим документом Perl здесь:

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

и

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...

Оба устанавливают хэш %data на first=>"full name" для Флинтстоунов. Что бы вы предпочли увидеть в коде, приходящем к вам?

Обратите внимание, что во второй форме есть гоча: после завершающей метки должен быть текст или пробел, иначе вы можете получить Can't find string terminator "END" anywhere before EOF Я думаю, именно поэтому вы видите одинокий ; в некоторых документах, которые здесь есть ,

ИМХО, ; принадлежит после первого экземпляра тега here doc или кода, который следует за ним. Труднее читать, если это после закрывающего тега. Если закрывающий тег имеет форму, похожую на модификатор оператора или логику предупреждения или ошибки. Это просто мой личный гид по стилю.

...