Strip leading spaces from here-docs

Perl v5.26 steals Perl 6’s feature to strip leading whitespace from here-docs. I wrote about that for The Effective Perler, but here’s the same thing for Perl 6 here-docs. As with most things, the Perl 5 feature is slightly different.

Before v5.26, you had to start your here-doc lines at the beginning of the line. This doesn’t line up with the indention, which some people find annoying:

use v5;

sub say_something {
	my $string =<<'HERE';
This line is not indented
Neither is this line
And the delimiter is not indented
HERE

	print $string;
	}

say_something();

Perl 6 already strips leading whitespace from the lines inside a here-doc. It

use v6;

sub say_something {
	my $string = q:to/HERE/;
		This line is not indented
			But this line is indented
		And the delimiter is not indented
		HERE

	print $string;
	}

say_something();

The whitespace before the final delimiter is stripped from each line in the string:

This line is not indented
	But this line is indented
And the delimiter is not indented

This still works if you don't have the same whitespace before each line:

use v6;

sub say_something {
	my $string = q:to/HERE/;
		This line is not indented
			But this line is indented
And the delimiter is not indented
		HERE

	print $string;
	}

say_something();

It works, but you get a warning (in Perl 5 this would be a compilation error). In my code I had two tabs; apparently it translates that into eight spaces:

This line is not indented
	But this line is indented
And the delimiter is not indented
Asked to remove 16 spaces, but the shortest indent is 0 spaces
  in any trim_heredoc at gen/moar/m-Perl6-Actions.nqp line 499

It tries to strip as much whitespace as it can (up to the amount in front of the delimiter). Since it considers a tab as eight spaces, the amount of space it strips might make the string look different than your typing. This version has a mix of spaces and tabs (although something might translate this example before you get it):

use v6;

sub say_something {
	my $string = q:to/HERE/;
		This line has two tabs
			This line has three tabs
                But this one has 16 spaces
		HERE

	print $string;
	}

say_something();

Allow it looks like the last line is indented more, when it converts tabs to eight spaces, the third line isn't indented at all:

This line has two tabs
	This line has three tabs
But this one has 16 spaces

But, a tab isn't just eight spaces. It's the number of spaces to get to the next multiple of 8. The last line of this here-doc mixes tabs and spaces:

use v6;

sub say_something {
	my $string = q:to/HERE/;
		This line has two tabs
			This line has three tabs
    	    But this one has 4 spaces, a tab, and 4 spaces
		HERE

	print $string;
	}

say_something();

You get a warning. This time it thinks there are 12 spaces in the last line:

This line has two tabs
	This line has three tabs
But this one has 4 spaces, a tab, and 4 spaces
Asked to remove 16 spaces, but the shortest indent is 12 spaces
  in any trim_heredoc at gen/moar/m-Perl6-Actions.nqp line 499
It's the same thing with more leading spaces:
use v6;

sub say_something {
	my $string = q:to/HERE/;
		This line has two tabs
			This line has three tabs
       	    But this one has 7 spaces, a tab, and 4 spaces
		HERE

	print $string;
	}

say_something();

So, be careful how you specify those leading spaces (and how you accept patches and so on).

Leave a Reply

Your email address will not be published. Required fields are marked *