Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

'Ambiguous call' diagnosis seems ambiguous

by anazawa (Scribe)
on Aug 03, 2012 at 00:08 UTC ( #985126=perlquestion: print w/replies, xml ) Need Help??
anazawa has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, 'warnings' pragma carps when a script calls a function ambiguously. To be more concrete,
A subroutine you have declared has the same name as a Perl keyword, and you have used the name without qualification for calling one or the other. Perl decided to call the builtin because the subroutine is not imported. (perldiag / Ambiguous call resolved as CORE::%s(), qualify as such or use &)
I think the above diagnosis is ambiguous in the following situation:
use strict; use warnings; sub each { warn 'main::each() was called' } sub delete { warn 'main::delete() was called' } my %person = ( name => 'Ken Takakura' ); while ( my ($key, $val) = each %person ) { print "$key: $val\n"; } delete $person{name};
In this case, 'warnings' pragma complains about each %person, but the pragma considers delete $person{name} not to be an ambiguous call. I think the pragma should complain about delete, too. What's the difference between each and delete calls in the above situation?

UPDATE: This article's title (Ambiguous calls) was renamed to "'Ambiguous call' diagnosis seems ambiguous" because the former was ambiguous.

Replies are listed 'Best First'.
Re: 'Ambiguous call' diagnosis seems ambiguous
by chromatic (Archbishop) on Aug 03, 2012 at 00:56 UTC

    Perl's tokenizer classifies some keywords as "weak keywords" such that you can override them with user-defined functions. (Calling them is another matter.) delete is a weak keyword and each is not. our is weak, but sub is not:

    use strict; use warnings; sub each { warn 'main::each() was called' } sub delete { warn 'main::delete() was called' } sub dump { warn 'main::dump() was called' } sub chop { warn 'main::chop() was called' } sub our { warn 'main::our() was called' } my %person = ( name => 'Ken Takakura' ); while ( my ($key, $val) = each %person ) { print "$key: $val\n"; } &our( $person{name} ); delete $person{name}; chop $person{name}; dump( $person{name} );

    I don't know how to make a list of weak and normal keywords without reading the source code (keywords.c or regen/

      Thanks for your suggestion. Your code output the following:
      Ambiguous call resolved as CORE::each(), qualify as such or use & at a line 12. Ambiguous call resolved as CORE::chop(), qualify as such or use & at a line 18. dump() better written as CORE::dump() at line 19. Ambiguous call resolved as CORE::dump(), qualify as such or use & at a line 19. name: Ken Takakura main::our() was called at line 8. Use of uninitialized value $person{"name"} in scalar chop at ambiguous line 18. Abort

      This result shows us that delete and our belong to "weak keywords", and each, chop and dump don't.

      The following was quoted from regen/

      145: -chop 160: +delete 163: -dump 164: -each 261: +our

      Plus (+) signs maybe mean "weak".

      Your comment meant a lot to me :)
Re: Ambiguous calls
by choroba (Bishop) on Aug 03, 2012 at 00:41 UTC
    The warning comes during the compilation phase (try adding a BEGIN block at the end of the programme). I guess it is because each is special - Perl must create an iterator for it (if it is the CORE:: one). Maybe the internals experts will tell us more.
      Thanks for your suggestion. I agree with you that each is special. According to chromatic's explanation, delete belongs to "weak keywords', and each doesn't. By the way, I'm not sure how to add a BEGIN block to my code. Would you please attach your code?

        I think choroba’s point is that you can use BEGIN blocks to determine when the warning is issued. For example:

        #! perl use strict; use warnings; BEGIN { print "BEGIN 1\n"; } sub each { warn 'main::each() was called' } BEGIN { print "BEGIN 2\n"; } sub delete { warn 'main::delete() was called' } BEGIN { print "BEGIN 3\n"; } my %person = (name => 'Ken Takakura'); while (my ($key, $val) = each %person) { print "$key: $val\n"; } delete $person{name}; BEGIN { print "BEGIN 4\n"; }

        produces this output:

        BEGIN 1 BEGIN 2 BEGIN 3 Ambiguous call resolved as CORE::each(), qualify as such or use & at 1 line 13. BEGIN 4 name: Ken Takakura

        which shows that the warning is issued during the compile phase (before the main code is executed) at the point where the code specifies an ambiguous call to each.

        This works because BEGIN blocks are executed during compilation, as soon as they are seen by the Perl compiler, before the main code is run. See BEGIN, UNITCHECK, CHECK, INIT and END.


        Athanasius <°(((><contra mundum

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://985126]
Approved by sundialsvc4
[marto]: "no it's not that"...."weirdos "...
[marto]: List EXE_FILES installed by CPAN so a couple of people suggest that your code looks obfuscated. I'd have to ageree, from the perspective of those who can't follow all of that one liner, it doesn't read well
Veltro is a weirdo, obsessed with whitespace
[marto]: to use the word "obsession" when so few people have said so little about it is grasping at staws
marto wishes tye was around, he's so much better at this sort of thing
usemodperl likes tye!
usemodperl tye  too
[choroba]: Re^3: LiBXML: New markup while preserving earlier tags? would benefit from a couple of test cases
usemodperl meant tye&nbsp;
usemodperl pokes Veltro with line noise

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2018-06-24 16:01 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (126 votes). Check out past polls.