PPI icon indicating copy to clipboard operation
PPI copied to clipboard

Heredocs are stripped from stringified Document object

Open h3xx opened this issue 1 year ago • 1 comments

Problem description

Stringifying the PPI::Document object (same as calling ->content() on it) strips out the content of heredocs, giving back an un-parseable document.

Example code:

#!/usr/bin/perl
use strict;
use warnings;
require PPI;
my $content = "my \$heredoc = <<~HERE;\n\tLine 1\n\n\tLine 3\n\tHERE\n";
my $doc = PPI::Document->new(\$content);
print $doc;

Which prints:

my $heredoc = <<~HERE;

Expected to print:

my $heredoc = <<~HERE;
        Line 1

        Line 3
        HERE

From what I've seen, the other tokens in the code are preserved, it's just heredocs that I found were affected.

  • PPI version: 93d6cb20accb627bb3d36cfce65d54168a091e71
  • Perl version: v5.38.0

Workaround

A workaround I've found is to call $doc->serialize instead. But this begs the question as to why the object stringifies at all if it produces broken code.

Notes

I investigated, and apparently the PPI::Token::HereDoc object only sets ->{content} to the first line. It should set it to the entire heredoc contents to fix the issue.

Possible other fix is to do use overload '""' => 'serialize' instead of => 'content'.

h3xx avatar Aug 23 '23 16:08 h3xx

I encountered the same issue in perlimports:

https://metacpan.org/release/OALDERS/App-perlimports-0.000052/source/lib/App/perlimports/Document.pm#L1004-1006

oalders avatar Aug 23 '23 16:08 oalders