tags:

views:

192

answers:

5
print <<EOF
stuff
EOF
;


print <<EOF;
stuff
EOF

Why would you use one over the other?

+12  A: 

Those two examples amount to the same thing behaviourally, but consider if you wanted to do something else after printing that block:

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

...or maybe you need to test the result of the operation:

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

These examples are contrived, but you can see how sometimes it can be useful to be flexible about what code comes after the block of text.

Ether
+1  A: 

FWIW, Perl Best Practices recommends:

print <<'EOF';
stuff
EOF
Wooble
Not the same thing. The single quotes suppress interpolation. The equivalent for the question would be with double quotes.
igelkott
@igelkott: and pbp recommends single quotes where there isn't actually any interpolation :)
ysth
There's no interpolation happening in the OP, though.
Andrew Medico
+5  A: 

You should treat heredoc tokens exactly like the string literals that they are. Do not delay further punctuation or syntax until after their contents. That's misleading and error-prone. Here are ten examples all taken from real code:

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

See how that works?

tchrist
+6  A: 

As tchrist points out, one thing that most people neglect is that the heredoc operator takes arbitrary perl code after the termination code.

This means that you can do (arguably) more natural looking manipulation, such as:

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

One consequence is that you can also stack them MUCH more readably (in my opinion ;) than "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

verses an unstacked 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));
Sir Robert
+1  A: 

Randal Schwartz has a great article on here documents HERE.

There are several things to remember about here documents:

  1. The ; in Perl is the statement terminator and is required for all Perl statements (with some exceptions) including here documents strings;
  2. The here document is a funny looking statement that is really just a big string;
  3. There must be a terminating CR to a here document (unlike most other Perl statements);
  4. You can have arbitrary Perl code either immediately after the opening tag or after the closing tag. If after the closing tag, it must be on a separate line. In either case, the code operates on the text of the here string;
  5. The quotes you use on the tags affect the string. Double quotes are like double quote strings in Perl, single quotes do not interpolate, back quotes get passed to the shell. No quotes are equivalent to double quotes;
  6. TIMTOWTDI, but some are forms are hard to read;
  7. Quoting from perldoc -q "HERE documents" (and perlfaq4):

    There must be no space after the << part.

    There (probably) should be a semicolon at the end [of the << part].

    You can’t (easily) have any space in front of the tag.

The two forms you have are functionally equivalent. Just as { ... } if (blah blah) is the same as if (blah blah) { ... }. While these two statements are functionally equivelent they "read" differently.

Each of these is equivalent and valid Perl here documents:

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

and

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

Both set the %data hash to first=>"full name" for the Flintstones. Which would you rather see in code coming to you?

Note the second form is one where there is a gotcha: There needs to be text or whitespace after the terminating mark or you may get Can't find string terminator "END" anywhere before EOF I think that is why you see the lone ; on some people's here docs.

IMHO, the ; belongs after the first instance of the here doc tag or the code that follows it. It is harder to read if it is after the closing tag. Unless the closing tag is in a form similar to a statement modifier or a warning or die logic. That is just my personal style guide.

drewk