Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between these two Perl snippets?

Tags:

heredoc

perl

print <<EOF
stuff
EOF
;


print <<EOF;
stuff
EOF

Why would you use one over the other?

like image 354
user318747 Avatar asked Oct 25 '10 15:10

user318747


3 Answers

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.

like image 90
Ether Avatar answered Oct 31 '22 13:10

Ether


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));
like image 9
Sir Robert Avatar answered Oct 31 '22 12:10

Sir Robert


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?

like image 4
tchrist Avatar answered Oct 31 '22 13:10

tchrist