Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

same warning multiple times when package in @ISA is not loaded

while refactoring some of my perl code i noticed the following strang behaviour.
consider this small sample script:

#!/usr/bin/perl -w

package test;
use strict;
my $obj = bless( {}, __PACKAGE__);
our @ISA = qw( missing );

exit(0)

the expected warning

Can't locate package missing for @test::ISA at test.pl line 8

appears three times instead of only one time. what are the other two triggers for this warning? all three refer to exit(0).
perl-version 5.12.4 on gentoo linux.

thanks.

like image 895
Nico Rittner Avatar asked Nov 11 '13 11:11

Nico Rittner


1 Answers

I believe tjd got the answer. If you add a DESTROY() and AUTOLOAD() method to the test package, you will get only one warning (about the absence of @test::ISA).

   package test;
   use strict;

   sub DESTROY {}
   sub AUTOLOAD {}

You generally need to make sure that the packages listed in the @ISA list have already been loaded. In your example, you might have expected to see something like:

   package test;  
   use strict;
   use missing;

   our @ISA = ('missing');

It is a bit curious that your package doesn't have an explicit new() method. Instead, you have a statement that calls bless();

If you had a new() method, like this:

   sub new() { return bless {}, __PACKAGE__; }

Then you would not see the triple error message until something called new();

   package main;
   my $object = test->new(); # Triple warning

You might want to use the pragma 'base', which will give you a fatal error saying that it cannot load the 'missing' package:

   package test; 
   use strict;
   use base ('missing');

   sub new { bless {}, __PACKAGE__);

The base pragma attempts to load the missing package for you. You do not need a separate 'use missing' statement.

So the final thing might look like this:

   package test;
   use strict;
   use warning;
   use base ('missing');

   sub new { bless {}, __PACKAGE__);
   sub DESTROY {}
   sub AUTOLOAD {}
   1;

You could then wrap this all into a file called test.pm and use it in a script:

   use strict;
   use test;

   my $object = test->new(); # Should fatal, as there is no 'missing' module

Hope this helps.

like image 72
jjohn Avatar answered Oct 10 '22 21:10

jjohn