13

EDIT: Note to new Perl programmers: This mechanism should NOT be used for multiline comments! It has a flaw decreases readability.

In this PerlMonks post on mechanisms to produce multiline comments in Perl, Abigail provided this one, that perplexes me:

The problem with just using a here document is that it will issue a warning under '-w'. It's much better to use the little known << >> operator.

<<q=~q>>;
  This is a multiline comment.
q

Running it through -M0=Deparse gives:

"  This is a multiline comment.\n" =~ //;
-e syntax OK

Can someone tell me what is going on?

Joel Berger
  • 20,180
  • 5
  • 49
  • 104
  • 2
    Wow, I feel sheepish! The answer was staring me in the face. The magician has you looking at the left hand (`<<`) and then its the right hand (`>>`) that fools you. – Joel Berger Mar 26 '11 at 16:13

3 Answers3

15

Abigail's answer is partly humorous. There is in fact no << >> operator (not in versions of Perl before 5.22), but there is a (not that well-known, I guess) << operator. Not the binary shift operator, but the unary here-document (heredoc for short). A simple form of it is:

$long_string = <<EOF;
This is a long, multiline string.
It ends when EOF appears alone on a line.
It will be assigned to the \$long_string variable.
EOF

This is, in fact, the “multiline comment” feature underlying Abigail's answer — a multiline string literal. The rest is a bit of somewhat obfuscated Perl.

The bareword or quoted string after << ends the string literal. You can use q as a bareword:

<<q;
This is a multiline comment, or rather a string literal whose value is ignored.
q

To understand the rest of Abigail's snippet, it helps to rewrite the here-document into a simple string literal:

"This is a multiline comment.\n" =~ q>>;

Ok, now q>> is the q quote-like operator with > as the delimiter character. q>> is equivalent to '' (a non-interpolated literal, which happens to be empty). So the string literal is matched against an empty pattern. The result of that matching is ignored anyway, but this clobbers the match result variables ($1, $&, etc).

Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • 1
    Damn, beat me by 47 seconds. And that just because I was testing my program fragment to make sure I didn't typo. I'll give you +1 anyway, despite my bitterness. ;) – Anomie Mar 26 '11 at 15:24
  • 1
    Of course I knew about the heredoc `<<`, I just can't believe I didn't see the `q{}` hidden in the `q>>`! WOW I feel sheepish. This whole thing, as I suspected it would, reminds me of the `-->` operator I've seen elsewhere `perl -E '$x=5;say $x while ($x --> 0);'`. – Joel Berger Mar 26 '11 at 16:01
  • 2
    I should say that the `q` operator is not the regex quote operator (`qr`) but is rather the non-interpolating quote operator – Joel Berger Mar 26 '11 at 16:26
  • I’ve lately been calling the `<<` operator *the hasta operator*, as in `<<"La_Vista"`. – tchrist Mar 26 '11 at 17:21
  • There is a `<< >>` operator starting with Perl 5.22. – mob Sep 30 '15 at 13:21
  • @mob Thanks for the notice. I don't have Perl 5.22 around here yet, does it break this code? – Gilles 'SO- stop being evil' Sep 30 '15 at 14:21
11

Hah. There is no such thing as a "<< >>" operator. What's going on there is basically equivalent to this:

"" =~ ''

=~ is, of course, the normal pattern-binding operator you normally use with m// or s///. The '' is using the q{} syntax for literal strings, with > as a delimiter, and is interpreted as a pattern at run-time. The "" is a here-doc with q as the terminating string.

I certainly wouldn't call this a comment though. Consider the output of this program fragment:

"copacetic" =~ q/(c[a-z]+)/;
print "$1\n";

<<q=~q>>;
    This is crap, not a comment!
q

print "$1\n";
Anomie
  • 92,546
  • 13
  • 126
  • 145
  • after looking at my Deparse results I wondered if that wouldn't happen. I voted you up, other people should too! Too bad there can only be one correct. Thanks! – Joel Berger Mar 26 '11 at 16:17
5

The following isn't as pretty, but it results in no executable code.

0 && <<COMMENT
...
COMMENT
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 2
    in the vein of tchrist, even better seems to be the pod format as comment command `=for comment` which is ignored by `perl` and `perldoc` (as well as other `pod` readers). However this wasn't really my question. – Joel Berger Mar 26 '11 at 18:59