Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re^3: Quote and Quote-like Operators

by choroba (Cardinal)
on Dec 16, 2011 at 00:38 UTC ( [id://943860]=note: print w/replies, xml ) Need Help??


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        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://943860]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2024-04-25 11:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found