http://www.perlmonks.org?node_id=1047098


in reply to Re: Eliminating "used only once" warnings from List::Util::reduce
in thread Eliminating "used only once" warnings from List::Util::reduce

That's a good guess. If you place a "warn" inside of BEGIN, UNITCHECK, CHECK, INIT, and END blocks, you'll see that the "only once" warning comes immediately after the BEGIN, but before UNITCHECK. It's being generated before runtime, so by the time the subroutine is actually called, it's too late.

Those solutions that deal with import are probably the best answer, though it wouldn't fix fully-qualified usages of reduce (where there is no import call).

I think a better solution would simply be for Perl to completely ignore $a and $b with respect to "used only once" warnings. Those should be additionally special-cased. Now to code-dive again and find where that could be implemented.


Dave

Replies are listed 'Best First'.
Re^3: Eliminating "used only once" warnings from List::Util::reduce
by BrowserUk (Patriarch) on Jul 30, 2013 at 19:12 UTC
    I think a better solution would simply be for Perl to completely ignore $a and $b with respect to "used only once" warnings.

    The biggest problem is: which $s & $b?

    That is, it is fairly easy to preempt the warnings for $main::a & $main::b -- by soemthing as simple as BEGIN{ $main::a || $main::b } somewhere in List::Util.pm; -- but if reduce() is called from some other package they won't be the right ones. Ie. If reduce() is called from package fred,then it'll be $fred::a & $fred::b.

    And there is no way to determine which package you were called from at BEGIN time. With this added to List::Util.pm:

    BEGIN{ printf "'%s'\n", scalar caller(); $main::a || $main::b }

    The current package at BEGIN time is main for both of these:

    C:\test\primes>perl -Mstrict -MList::Util=reduce -wE" say reduce{ $a + +$b } 1,2,3" 'main' 6 C:\test\primes>perl -Mstrict -wE"package fred; use List::Util qw[ redu +ce ]; say reduce{ $a +$b } 1,2,3" 'main' Name "fred::a" used only once: possible typo at -e line 1. Name "fred::b" used only once: possible typo at -e line 1. 6

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Yes, that's the problem with simple fixes. I actually thought of something similar to the BEGIN{ $main::a... trick and submitted it months ago for List::MoreUtils::pairwise, where it was eventually pointed out (as I should have realized myself) that it would only work for the first invocant of use Modulename.

      On the other hand, import does have caller context. So a fix could be applied within import. But as I mentioned in another post in this thread, that wouldn't solve times where the user skips import with "use List::Util ();, and then fully-qualifies List::Util::reduce in his code.

      So, this can be mostly fixed by overriding import. But probably instead should be fixed within the Perl interpreter so as to special-case $a and $b further. They already have special case treatment for strict vars. One step further isn't going to suddenly allow a bunch of "only once" bugs to slip through people's code.


      Dave

        But probably instead should be fixed within the Perl interpreter so as to special-case $a and $b further.

        I always thought that it would be (would have been) better to use $A & $B for this instead.

        That might at least prevent all these pointless "Don't use $a & $b" pseudo-commandments.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^3: Eliminating "used only once" warnings from List::Util::reduce
by tobyink (Canon) on Jul 30, 2013 at 20:29 UTC

    Yes, the reason it happens after the BEGIN stage rather than during, when most compile-time warnings are issued, is that Perl needs to check the whole lexical scope (i.e. file probably) before it can issue any warnings about variables being used only once. (Because until it's got to the end of the scope it cannot be sure they were only used once.)

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name