andal has asked for the wisdom of the Perl Monks concerning the following question:

The gentoo has upgraded perl to perl-5.12 and immidiately one of my modules stopped to work. The error was somewhat weird, so after playing with deleting pieces of code I reduced everything to the following 2 files

try.pl

#!/usr/bin/perl use strict; use MyPackage; MyPackage::close_cnx();

MyPackage.pm

package MyPackage; use strict; use constant INIT => 4; sub close_cnx { my $self = shift; init_action($self); } sub init_action { my $self = shift; return if $self->{Needed} <= $self->{count}; callit($self->{ID}, INIT); } 1;

An attempt to execute "try.pl" results in the message

Undefined subroutine &main::Needed called.
INIT failed--call queue aborted.

Enabling warnings clarifies, that the problem may be from the conflicting use with the INIT block. But if such use is so disastrous, why is it not a syntax error? Are there some reasons to have it only as warning?

Replies are listed 'Best First'.
Re: Conflict with INIT block is not an error?
by toolic (Bishop) on Oct 26, 2010 at 13:29 UTC
    why is it not a syntax error?
    In my opinion, it is a syntax error on 5.12. When I add a print to your try.pl file, I get the same error message as you do, and it does not print "foo". On 5.8.8, I get no error message and it does print "foo".
    #!/usr/bin/perl use strict; use MyPackage; MyPackage::close_cnx(); print "foo\n";

    As an aside, you can promote warnings to errors like this:

    use warnings FATAL => 'all';
Re: Conflict with INIT block is not an error?
by Anonymous Monk on Oct 26, 2010 at 14:07 UTC
    I think it would be hard to make it a syntax error, as that would mean the parser would have to detect a problem when parsing the INIT token in use constant INIT => 4. The latter, though, is just a regular fat-comma-quoted string which is passed as argument to constant.pm's import function.

    OTOH, constant.pm could in theory be made to croak instead of just issuing a warning, as it currently does

    # Maybe the name is tolerable } elsif ($name =~ $tolerable) { # Then we'll warn only if you've asked for warnings if (warnings::enabled()) { if ($keywords{$name}) { warnings::warn("Constant name '$name' is a Perl keyword");

    But maybe whoever wrote that code had some curious usage of such keyword/subroutine redefinition in mind, in which case a fatal error might be inappropriate here? After all, you can make warnings fatal yourself, as already mentioned above.

      It shouldn't croak for BEGIN.

      $ perl -le'use constant BEGIN => 4; print(BEGIN);' 4

      But I'm all for having it croak for INIT.

      $ perl -le'use constant INIT => 4; print(INIT);' Undefined subroutine &IO::File::AUTOLOAD called. INIT failed--call queue aborted.

      A bug report can be filed.