Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Can't include a HEREDOC within RHS of a Regex

by wind (Priest)
on Jun 15, 2011 at 00:15 UTC ( [id://909675]=perlquestion: print w/replies, xml ) Need Help??

wind has asked for the wisdom of the Perl Monks concerning the following question:

Howdy Fellow Monks,

I recently attempted to include a heredoc within the eval'd rhs of a regex. No matter what I attempted, perl died with the following error:

Can't find string terminator "END_TEXT" anywhere before EOF

I've reduced this code to the following example:

use strict; use warnings; my $data = "line1\nfoobar\nline3\n"; $data =~ s{(foo)(bar)}{ my $one = $1; my $two = $2; $one .= <<'END_TEXT'; Insert 1 Insert 2 END_TEXT $one.$two; }e; print $data;

Obviously, one can "fix" the issue by using an ordinary string instead, but I would like y'alls advice concerning this.

Super searching revealed only one thread connected to both heredoc's and regex, but it was unrelated.

Thanks

Update: Anon monk pointed out that it does work when outside of the RHS of the regex:

$data =~ s{(foo)(bar)}{ my $one = $1; my $two = $2; $one .= <<'END_TEXT'; $one.$two; }e; Insert 1 Insert 2 END_TEXT

Replies are listed 'Best First'.
Re: Can't include a HEREDOC within RHS of a Regex
by Anonymous Monk on Jun 15, 2011 at 02:54 UTC
    use strict; use warnings; my $data = "line1\nfoobar\nline3\n"; $data =~ s{(foo)(bar)}{ my $one = $1; my $two = $2; $one .= <<'END_TEX +T'; $one.$two; }e; Insert 1 Insert 2 END_TEXT print $data;
    Works like a champ
    Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:\Documents and Settings\Neva>cd \code\Jff C:\code\JFF>perl regex.pl line1 foo Insert 1 Insert 2 bar line3

      ...and that syntax applied to the simpler version:

      use strict; use warnings; use 5.010; my $data = "greeting"; $data =~ s{greeting} {my $repl = <<"END_OF_STR"; "$repl goodbye mars"; }e; hello world END_OF_STR say $data; --output:-- hello world goodbye mars

        ...and that syntax applied to the simpler version:

        While your code is quite revealing, your explanation leaves to be desired. You seem to be saying the following snippets are equivalent:

        print "a", <<"END_OF_STR", "c"; b END_OF_STR
        print "a", <<"END_OF_STR", "c"; b END_OF_STR

        They're not.

Re: Can't include a HEREDOC within RHS of a Regex
by ikegami (Patriarch) on Jun 15, 2011 at 07:20 UTC
    The parser needs to find the end of the s/// operator to find the flags before it even tries to parse the replacement expression as code. That means the lexer points to the end of the substitution operator when the heredoc is first encountered. That is why the parser looks after the substitution for the heredoc body, as shown in Re^2: Can't include a HEREDOC within RHS of a Regex.

      Should this be reported as a bug?

      I understand the "why" and there definitely isn't a big need for this type of functionality. However, the RHS of a regex should behave like any other eval block in my opinion.

      The last time I found a bug you reported it for me. Should this one be reported as well?

      I only discovered this while helping someone else on a different forum, so I don't foresee any lost sleep for anyone if this isn't fixed. It also might introduce new problems given there is a "work around" that might've used by others in the past. Can't say which action would be best.

        I don't see what could be done about it, really. Maybe a documentation fix? But I think that would clutter up the docs more than anything.
Re: Can't include a HEREDOC within RHS of a Regex
by Anonymous Monk on Jun 15, 2011 at 02:52 UTC
    but I would like y'alls advice concerning this.

    It is a bug. There is no test for this in the testsuite

    ack "<<" perl/t/re
Re: Can't include a HEREDOC within RHS of a Regex
by 7stud (Deacon) on Jun 15, 2011 at 01:04 UTC

    I've reduced this code to the following example:

    Too complicated. Same error here:

    my $data = "greeting"; $data =~ s{greeting} {my $repl = <<"END_OF_STR"; hello world END_OF_STR "$repl goodbye mars" }e;

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (None)
    As of 2024-04-25 00:23 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found