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

Re: lib/_charnames.pm puts references in %^H

Thread Previous | Thread Next
From:
demerphq
Date:
June 14, 2017 23:11
Subject:
Re: lib/_charnames.pm puts references in %^H
Message ID:
CANgJU+VKYFA_45sSFLTPNLQi0FW3XuG+1EwwKeAkqBDy6O0tAg@mail.gmail.com
On 14 June 2017 at 21:56, Zefram <zefram@fysh.org> wrote:
> Paul "LeoNerd" Evans wrote:
>>Except its wording here isn't quite right. What %^H does is that values
>>are stringified at the point when compilation is over and runtime (for
>>that block) starts.
>
> No, perlvar(1) is closer to the truth.  What *actually* happens is that
> anything written to %^H is immediately stored in two places.  It's stored
> as-is in the actual %^H hash, but it's also stored in a flattened form
> (involving stringification of references) in an alist-like structure
> that hangs off the COP of compiling code.
>
> During compilation, the %^H content applicable to the current point
> of compilation can be read straight from %^H.  By nature this yields
> the actual value that was written, including references as references.
> However, this mechanism can't examine the %^H content for any location
> other than the present compilation point.
>
> At any time (compilation, runtime, whatever), the %^H content applicable
> to any piece of compiled code can be read from the alist referenced by its
> COP.  This yields the flattened value.  The flattening is the cost of this
> being available for code other than that which is currently compiling.
>
> So what distinguishes between stringified references and intact
> references isn't timing, it's the mechanism from which the value is
> being read.  The note in perlvar(1) about "at runtime" refers to the
> fact that reading %^H for currently-running code must be via the COP,
> hence in the flattened form.  perlvar(1) is slightly wrong in saying "the
> entries are stringified when accessed", and you're wrong in saying they're
> stringified "when compilation is over": they were actually stringified
> during compilation, at the same time they were written into %^H.
>
>>If this is the case: does anyone have any suggestions on how I might
>>stop it triggering a warning from my code?
>
> Detect that the stringification is being performed for %^H-in-COP purposes
> and refrain from warning in that situation.
>
>>                                           I feel that _charnames.pm
>>is doing something slightly naughty here,
>
> It is not at all naughty.  The compile-time behaviour of %^H is
> intentional and supported, and predates by two major versions the
> availability of the shadow of %^H in the COP.

All this sounds reasonable, but I cant square what is said in the
docs, especially about charnames, and the behavior of the following
one liner:

./perl -Ilib -le'BEGIN{ print "0:$^H:$^H{t}" }; print "1:$^H:$^H{t}";
BEGIN{ $^H |= 0x04020000; $^H{t}="x"; } BEGIN{ print "2:$^H:$^H{t}"; }
{ BEGIN{ $^H{t}="y"; } BEGIN { print "3:$^H:$^H{t}" } print
"4:$^H:$^H{t}" } BEGIN{ print "5:$^H:$^H{t}"; } print "6:$^H:$^H{t}"'

0:0:
2:67240192:x
3:67239936:y
5:67240192:x
1:256:
4:256:
6:256:

That is, I would have expected that $^H{t} would be set in 4 and 6 to
'y' and 'x' respectively.

But the value that was set at compile time does not appear to be set
at run time.

I poked into this further and it seems to be true also fro $^H, which
makes me wonder about the docs for charnames, which seems to suggest
the following should print out "bytes", but it does not:

$ perl -le'use charnames (); use bytes (); sub translator {if ($^H &
$bytes::hints_bits) { print "bytes" } else { print "unicode" } return
"test" } BEGIN { $^H{charnames}= \&translator}; { use bytes; print
"\N{TEST}" } '
unicode
test

It seems like the documentation for charnames is wrong, or I am
missing something important.

Yves
-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

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