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 15, 2017 01:01
Subject:
Re: lib/_charnames.pm puts references in %^H
Message ID:
CANgJU+XXzpiSUPC3AEnPotrc4+=vEBe9GBkkE-ShGKs0MUZkYA@mail.gmail.com
On 15 June 2017 at 02:35, demerphq <demerphq@gmail.com> wrote:
> On 15 June 2017 at 01:33, Zefram <zefram@fysh.org> wrote:
>> demerphq wrote:
>>>But the value that was set at compile time does not appear to be set
>>>at run time.
>>
>> Yes, that's correct.  %^H's scoping behaviour is driven by the scoping of
>> code being compiled, not the scoping of code being run.  That's because
>> the value of %^H is lexical state that's in effect for the code being
>> compiled, not for the code being run.  When you're not compiling anything,
>> %^H behaves essentially as an ordinary hash.
>>
>> Since you didn't assign anything to $^H{t} during runtime of your test
>> program, of course it doesn't contain anything at runtime.  If you want
>> to see at runtime the $^H{t} value from compilation of the running code
>> (i.e., the lexical hint applying to the running code), you need to define
>> something like
>>
>>         sub ht { ((caller(0))[10] // {})->{t} }
>>
>> and print out its return value.
>>
>>>I poked into this further and it seems to be true also fro $^H,
>>
>> Same scoping behaviour.  caller item [8] to see at runtime the value
>> that it had at compile time of the running code.
>>
>>>$ 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}" } '
>>
>> $bytes::hints_bits is undefined.  You want $bytes::hint_bits, and with
>> that alteration this does print "bytes".
>
> I see. And that only works because translator() is being called at
> compile time. Would it be fair to say that it is as though the sub
> being called by "\N{TEST}" was wrapped in a BEGIN?
>
> BTW, I feel like the docs for $^H and %^H do not explain what you have
> explained in this thread at all. I think i will make a stab at a doc
> patch based on your words.

Does this make sense?

Branch: yves/doc_hints

sha1: 8c63298e068b2c72fa6e908c486b7d9985382324

commit 8c63298e068b2c72fa6e908c486b7d9985382324
Author: Yves Orton <demerphq@gmail.com>
Date:   Thu Jun 15 02:59:57 2017 +0200

    document hints variables better

    based on zeframs mails in thread "lib/_charnames.pm puts references in %^H"

diff --git a/pod/perlvar.pod b/pod/perlvar.pod
index 9ce9430..405a1e9 100644
--- a/pod/perlvar.pod
+++ b/pod/perlvar.pod
@@ -2101,13 +2101,15 @@ This variable was added in Perl 5.14.0.
 =item $^H
 X<$^H>

-WARNING: This variable is strictly for
-internal use only.  Its availability,
+WARNING: This variable is strictly for internal use only.  Its availability,
 behavior, and contents are subject to change without notice.

-This variable contains compile-time hints for the Perl interpreter.  At the
-end of compilation of a BLOCK the value of this variable is restored to the
-value when the interpreter started to compile the BLOCK.
+This variable is part of the lexical state of the compilation process
+and contains compile-time hints for the Perl interpreter. At the end of
+compilation of a block the value of this variable is restored to the value
+when the interpreter started to compile the block.  This behavior provides
+the semantic of lexical scoping, and is used in, for instance,
+the C<use strict> pragma.

 When perl begins to parse any block construct that provides a lexical scope
 (e.g., eval body, required file, subroutine body, loop body, or conditional
@@ -2116,8 +2118,12 @@ When the compilation of the block is completed,
it regains the saved value.
 Between the points where its value is saved and restored, code that
 executes within BEGIN blocks is free to change the value of C<$^H>.

-This behavior provides the semantic of lexical scoping, and is used in,
-for instance, the C<use strict> pragma.
+During run-time this variable is just like any other, and changes made during
+compilation are not directly visible via accessing the variable directly,
+instead you can find out at run time what value was in effect at a given point
+in the code by accessing item 8 of the return from caller:
+
+  sub hint_bits { (caller(0))[8] }

 The contents should be an integer; different bits of it are used for
 different pragmatic flags.  Here's an example:
@@ -2131,8 +2137,7 @@ different pragmatic flags.  Here's an example:

 Consider what happens during execution of the BEGIN block.  At this point
 the BEGIN block has already been compiled, but the body of C<foo()> is still
-being compiled.  The new value of C<$^H>
-will therefore be visible only while
+being compiled.  The new value of C<$^H> will therefore be visible only while
 the body of C<foo()> is being compiled.

 Substitution of C<BEGIN { add_100() }> block with:
@@ -2153,9 +2158,19 @@ X<%^H>

 The C<%^H> hash provides the same scoping semantic as C<$^H>.  This makes
 it useful for implementation of lexically scoped pragmas.  See
-L<perlpragma>.   All the entries are stringified when accessed at
-runtime, so only simple values can be accommodated.  This means no
-pointers to objects, for example.
+L<perlpragma>.
+
+Similar to $^H this variable is part of the lexical state of the compilation
+process, and changes made to it at compile time are not visible later on
+at a run time. Instead you can access those values by accessing the 10th
+slot of the return of caller:
+
+  sub hints_hash { (caller(0))[10] }
+
+During compilation this hash may be used to store complex structures, such
+as code references, however once compilation is completed these structures
+will be flattened to a representation that means that only simple values can
+be accommodated and retrieved at run time via C<caller()> as above.

 When putting items into C<%^H>, in order to avoid conflicting with other
 users of the hash there is a convention regarding which keys to use.
@@ -2163,6 +2178,9 @@ A module should use only keys that begin with
the module's name (the
 name of its main package) and a "/" character.  For example, a module
 C<Foo::Bar> should use keys such as C<Foo::Bar/baz>.

+During run time C<%^H> is essentially the same as any other hash, and any
+changes made to it during the compilation phase are not visible.
+
 This variable was added in Perl v5.6.0.

 =item ${^OPEN}




-- 
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