develooper Front page | perl.perl5.porters | Postings from June 2021

Re: qr'$foo' and unescaped $ signs

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
June 29, 2021 16:06
Subject:
Re: qr'$foo' and unescaped $ signs
Message ID:
20210629160618.GG11066@etla.org
On Tue, Jun 29, 2021 at 05:38:48PM +0200, Eirik Berg Hanssen wrote:
> On Tue, Jun 29, 2021 at 4:31 PM Nicholas Clark <nick@ccl4.org> wrote:
> 
> > So I guess, the question is:
> >
> > If the PV stored for a regex has an *unescaped* dollar sign in it it *has*
> > to have originated from a regex written with '' ?
> >
> 
>   I'm not sure I follow you all the way, but I don't think so.  It could
> come from an interpolated variable:

You followed enough to consider a case that I had not. Thanks...

> eirik@rustybox[17:33:04]~$ perl 2>&1 | grep PV
> use Devel::Peek;
> Dump($_) for qr'$foo', qr/${\q($)}foo/;
> __END__
>     PV = 0x55d52be518a0 "(?^:$foo)"
>       PV = 0x55d52be518a0 "(?^:$foo)"
>     PV = 0x55d52be714c0 "(?^:$foo)"
>       PV = 0x55d52be714c0 "(?^:$foo)"
> eirik@rustybox[17:33:24]~$
> 
> 
> > 1) the *only* way that could have got there was by being written as qr''
> >
> 
>   If I read you right, no, not quite.

You did.

> > 2) the *only* way to convert that back to a regex is to output qr''
> >    (ie there exists no escaping syntax capable of recreating it inside
> > qr//)
> >
> 
>   The only *other* way I know of, is through a variable.
> 
>   Perhaps Data::Dumper should output qr/(?^:${\q($)}foo)/;instead?

Thanks. That is something I'd not considered, and likely a solution.
I thought we were stuck - the possible solution I had to use qr'' then
fails if there's Unicode, because the XS code really wants to use \x{...}
escapes to encode that to keep the output as ASCII.

But you've suggested a syntax (hairy, but workable) where one can generate
an equivalent regex that has the literal $ in it, but is written in 7 bits.


ie, start with this, written with a shell heredoc to handle the ''s:

$ ./perl -Ilib -C63 -MDevel::Peek -w <<EOT                Dump(qr'$ ☃')
EOT
SV = IV(0x1332360) at 0x1332370
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x1332520
  SV = REGEXP(0x13663a0) at 0x1332520
    REFCNT = 1
    FLAGS = (OBJECT,POK,FAKE,pPOK,UTF8)
    PV = 0x1359a30 "(?^u:$ \342\230\203)" [UTF8 "(?^u:$ \x{2603})"]
    CUR = 11
    LEN = 0
...


but instead, dump it like this:

./perl -Ilib -C63 -MDevel::Peek -we 'Dump(qr/${\q($)} \x{2603}/)'
SV = IV(0x15e9aa0) at 0x15e9ab0
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x15e9af8
  SV = REGEXP(0x1604470) at 0x15e9af8
    REFCNT = 1
    FLAGS = (OBJECT,POK,FAKE,pPOK,UTF8)
    PV = 0x15df630 "(?^u:$ \\x{2603})" [UTF8 "(?^u:$ \\x{2603})"]
    CUR = 16
    LEN = 0
...

I think that this generalises.

Thanks.

There might be a winning move after all.

Nicholas Clark

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About