7
print <<EOF
stuff
EOF
;


print <<EOF;
stuff
EOF

你为什么要使用一个而不是另一个?

4

5 回答 5

14

这两个示例在行为上等同于同一件事,但请考虑在打印该块后是否想做其他事情:

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

...或者您可能需要测试操作的结果:

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

这些示例是人为设计的,但您可以看到有时灵活地处理文本块之后的代码是多么有用。

于 2010-10-25T16:12:06.600 回答
9

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

诗句未堆叠的heredoc ...

-- 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));
于 2010-10-25T19:29:00.373 回答
4

您应该像对待字符串文字一样对待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};

看看它是如何工作的?

于 2010-10-25T18:59:13.343 回答
2

FWIW,Perl 最佳实践建议:

print <<'EOF';
stuff
EOF
于 2010-10-25T16:12:16.337 回答
1

Randal Schwartz在此处的文档中有一篇很棒的文章

关于这里的文档,有几件事要记住:

  1. ;in Perl 是语句终止符,所有 Perl 语句(除了一些例外)都需要它,包括这里文档字符串;
  2. 这里的文档是一个看起来很有趣的声明,实际上只是一个大字符串;
  3. 此处文档必须有一个终止 CR (与大多数其他 Perl 语句不同);
  4. 您可以在开始标记之后或结束标记之后立即使用任意 Perl 代码。如果在结束标记之后,它必须在单独的行上。在任何一种情况下,代码都会对 here 字符串的文本进行操作;
  5. 您在标签上使用的引号会影响字符串。双引号就像 Perl 中的双引号字符串,单引号不插入,反引号被传递给 shell。无引号等价于双引号;
  6. TIMTOWTDI,但有些表格很难阅读;
  7. 引用自perldoc -q "HERE documents"(和perlfaq4):

<< 部分后面不能有空格。

<<在 [部分]的末尾(可能)应该有一个分号。

您不能(轻松)在标签前面有任何空间。

您拥有的两种形式在功能上是等效的。就像{ ... } if (blah blah)是一样if (blah blah) { ... }。虽然这两个语句在功能上是等效的,但它们的“读取”方式不同。

这些中的每一个都是等效且有效的 Perl here文档:

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

两者都为 Flintstones设置了%data哈希值。first=>"full name"您更愿意在代码中看到哪个?

请注意,第二种形式有一个陷阱:在终止标记之后需要有文本或空格,否则您可能会得到Can't find string terminator "END" anywhere before EOF. 我认为这就是为什么您会;在某些人的此处文档中看到孤独的原因。

恕我直言,;属于here doc 标记的第一个实例或其后面的代码之后。如果它在结束标记之后,则更难阅读。除非结束标签的形式类似于语句修饰符或警告或逻辑。那只是我个人的风格指南。

于 2010-10-26T01:35:45.967 回答