[prev in list] [next in list] [prev in thread] [next in thread] 

List:       perl5-porters
Subject:    Re: Hints hash changes
From:       Dave Mitchell <davem () iabyn ! com>
Date:       2020-03-12 15:58:32
Message-ID: 20200312155832.GR4848 () iabyn ! com
[Download RAW message or body]

On Mon, Feb 17, 2020 at 04:08:40PM +0000, David Cantrell wrote:
> On Mon, Feb 17, 2020 at 11:50:26PM +1100, Tony Cook wrote:
> > On Mon, Feb 17, 2020 at 10:57:56AM +0000, David Cantrell wrote:
> > > Thanks to the CPAN-testers I came across a change in how the hints hash
> > > is handled which I can't find documented, nor can I see any commit
> > > message about it, leading me to think that the change might have been an
> > > accidental side-effect.
> > > 
> > > It happened somewhere in between 5.31.6 and 5.31.7, as can be seen here:
> > >   http://matrix.cpantesters.org/?dist=Devel-Hide+0.0012
> > 
> > Do you have a brief example that demonstrates the change?
> 
> Here you go:
> 
> ~ $ cat Foo.pm
> package Foo;
> 
> use strict;
> use warnings;
> 
> sub import {
>     shift;
>     my @args = @_;
> 
>     foreach my $arg (@args) {
>         if($arg eq '-quiet') {
>             $^H{"Foo/quiet"} = 1;
>         }
>     }
>     my $hintshash = (caller(1))[10];
>     exit !$hintshash->{"Foo/quiet"}
> }
> 
> 1;
> ~ $ perlbrew switch perl-5.31.6
> ~ $ perl -I. -e 'use Foo qw(-quiet)';echo $?
> 0
> ~ $ perl -I. -e 'use Foo qw(pirates)';echo $?
> 1
> ~ $
> ~ $ perlbrew switch perl-5.31.7
> ~ $ perl -I. -e 'use Foo qw(-quiet)';echo $?
> 1
> ~ $ perl -I. -e 'use Foo qw(pirates)';echo $?
> 1

The change in behaviour was a side-effect of my fix for recording caller
data correctly, but I think the change makes behaviour actually match the
docs (although they are a bit vague). So I think the bug-fix is correct.

In particular, I've I've just pushed the following commit:

    commit ee428a211d040dc56d9efc4a89c96886a398fc1c
    Commit:     David Mitchell <davem@iabyn.com>
    CommitDate: Thu Mar 12 15:41:24 2020 +0000

    docs: clarify effect of $^H, %^H, ${^WARNING_BITS}
    
    See http://nntp.perl.org/group/perl.perl5.porters/257128


    +Each time a statement completes being compiled, the current value of
    +C<%^H> is stored with that statement, and can later be retrieved via
    +C<(caller($level))[10]>.

    ....

Internally, each time a statement is compiled, an OP_NEXTSTATE COP is
prepended to the optree for that statement, which records the file,
line-number, %^H etc in force at that moment in compilation.

Later whenever a sub is called or similar, the COP in action at the time
of calling is pushed onto the context stack. caller($level) makes use of
the COP linked to at $level of the stack to determine the line number,
hints etc at the call site. 

The bug I originally fixed was that during nested use's, the shared
PL_compiling COP was reused and so appeared in several places on the
context stack, meaning that line numbers (and hints etc) for upper call
sites were being incorrectly reported as being the same as the inner-most
call site.

In your particular example above, 'use Foo qw(-quiet)' is equivalent
to

    BEGIN {
        require Foo;
        Foo->import('-quiet);
    }

At the point when the BEGIN has just been compiled, %^H is not yet
modified, so the statements within the BEGIN block are all associated with
the default %^H values - in particular the statement which calls the import
method.  When BEGIN, and thus import(), are subsequently called, %^H is
modified by import() and as compiling resumes at the line following the
BEGIN, any such statements pick up the modified %^H value.

-- 
In economics, the exam questions are the same every year.
They just change the answers.
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic