print <<EOF
stuff
EOF
;
print <<EOF;
stuff
EOF
你为什么要使用一个而不是另一个?
这两个示例在行为上等同于同一件事,但请考虑在打印该块后是否想做其他事情:
print <<EOF
stuff
EOF
. "more text here";
...或者您可能需要测试操作的结果:
print $unstable_filehandle <<EOF
stuff
EOF
or warn "That filehandle finally disappeared: $!";
这些示例是人为设计的,但您可以看到有时灵活地处理文本块之后的代码是多么有用。
正如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));
您应该像对待字符串文字一样对待heredoc 标记。不要将更多的标点或语法延迟到其内容之后。这是误导和容易出错的。这里有十个例子都取自真实代码:
($is_a_valid_rfc_822_addr = <<'EOSCARY') =~ s/\n//g;
$eval = (($Preamble=<<'END1') . $userstuff . <<'END2');
for my $line (<<"End_of_Property_List" =~ m{ \S .* \S }gx) {
$cases .= <<"EDQ" if $timeout;
($is_a_valid_rfc_822_addr = <<'EOSCARY') =~ s/\n//g;
eval (($Preamble=<<'END1') . $_[0] . <<'END2');
@changes = split("\n", <<"EOCHANGES");
$change .= sprintf(<<"EOP", $in, $out, $in, $out);
eval "{ package $package; " . <<'EOF' . "}";
push @args, dequeue('|Q|', <<'END_OF_ASTRAL_MATCH') if $Opt{astral};
看看它是如何工作的?
FWIW,Perl 最佳实践建议:
print <<'EOF';
stuff
EOF
Randal Schwartz在此处的文档中有一篇很棒的文章。
关于这里的文档,有几件事要记住:
;
in Perl 是语句终止符,所有 Perl 语句(除了一些例外)都需要它,包括这里的文档字符串;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 标记的第一个实例或其后面的代码之后。如果它在结束标记之后,则更难阅读。除非结束标签的形式类似于语句修饰符或警告或死逻辑。那只是我个人的风格指南。