in reply to Re^2: Quote and Quote-like Operators
in thread Quote and Quote-like Operators

One can include spaces in the terminating string:
sub foo { xsh <<' end ;' open 1.xml ; delete //@id ; save :b ; end ; }
:-)

Replies are listed 'Best First'.
Re^4: Quote and Quote-like Operators
by jmcnamara (Monsignor) on Dec 16, 2011 at 10:26 UTC

    Yes, but in that case printing the contents of the heredoc will print the indentation as well.

    A better solution would be if perl removed whatever leading whitepsace came before the heredoc (or the end token) from the text of the heredoc. Then the heredoc could be indented to match the surrounding code. In that case I would use it more often.

    I'm not saying that heredocs aren't useful. Just that they break indentation.

    --
    John.

      I'm not saying that heredocs aren't useful. Just that they break indentation.
      Then you’re just doing them wrong. :)
      sub compile_filter() { my @criteria; for my $i ( 0 .. $#ARGV ) { my $snippet = $ARGV[$i]; $snippet =~ s/^\s+//; # prime the autoloader on allcappish barewords if (my @capwords = $snippet =~ /\b (?=[A-Z]) ([A-Z0-9]+) \b/xg +) { eval deQQ<<"EO_AUTOLOADED_SUBS"; |QQ| |QQ| use subs qw(@capwords); |QQ| EO_AUTOLOADED_SUBS } # args starting with a backslash or which are a bracketed # espression are interpreted as pattern matches if ($snippet =~ m{ ^ \\ | ^ \[ .* \] $ }x) { $snippet = "/$snippet/"; } my $test_compile = deQ <<'START_TEST'; |Q| use warnings qw[FATAL all]; |Q| my $ignore = START_TEST $test_compile .= deQQ(<<"END_TEST"); |QQ| sub { $snippet }; |QQ| |QQ| # so eval returns true |QQ| 1; |QQ| END_TEST # debug("test compile:\n$test_compile"); eval($test_compile) || die "$0: invalid criterion in '$snippet': $@\n"; $criteria[$i] = "do { $snippet }"; } my $real_code = deQ(<<'START_CODE') . "\t"; |Q| use warnings; |Q| #use warnings qw[FATAL all]; |Q| #no warnings qw[deprecated]; |Q| |Q| sub filter { |Q| |Q| debug(sprintf("testing code point %X", ord())) +; |Q| |Q| my $result = |Q| START_CODE $real_code .= join("\n &&\n\t" => @criteria) . deQ(<<'END_CODE'); |Q| |Q| ; |Q| |Q| debug("result of " . join(" && ",@criteria) . +" is $result"); |Q| return $result; |Q| } |Q| |Q| # so eval returns true |Q| 1; END_CODE debug("CRITERIA are\n$real_code"); eval($real_code) || die; }
      As you see, heredocs certainly don’t have to “break indentation”; it just takes a bit of creative processing to make ’em look purdy. The deQ and deQQ functions are trivial:
      sub dequeue($$) { my($leader, $body) = @_; $body =~ s/^\s*\Q$leader\E ?//gm; return $body; } sub deQ($) { my $text = $_[0]; return dequeue q<|Q|>, $text; } sub deQQ($) { my $text = $_[0]; return dequeue qq<|QQ|>, $text; }
      See how that all works?

      --tom

        Even with all of that clever work, go ahead a 'shift' any of those blocks of code over and watch your heredoc break. Your heredocs above break indentation (your terminators aren't indented). And (re)indentation breaks your heredocs.

        Perhaps worse, trailing whitespace can break a Perl heredoc. Plenty of reason to avoid using them in code I plan to maintain.

        - tye