perlprototypeperl5.10

Did Perl 5.10 mess something up with prototypes?


I know this type of thing I want to do used to work in 5.8. Am I doing something wrong? Is there a way to get back there in Perl 5.10?

Here's the module:

package TableMod;
use base qw<Exporter>;
our @EXPORT_OK = qw<mod_table>;

use Data::Dumper;
sub mod_table (\%@) { print Dumper( @_ ); }

1;

And here is the script:

use strict;
use warnings;
use Data::Dumper;
use Test::More tests => 4;

sub mod_table_here (\%@) { 
    print Dumper( @_ );
}

use_ok( 'TableMod', 'mod_table' );
can_ok( __PACKAGE__, 'mod_table' );
is( prototype( \&mod_table_here ), '\\%@'
  , q/prototype( \&mod_table_here ) = '\%@'/ 
  );
is( prototype( \&mod_table ), prototype( \&mod_table_here )
   , 'prototypes ARE the SAME!' 
   );
my %table = qw<One 1>;
mod_table_here %table => ( 1, 2, 3, 4 );
#mod_table %table => ( 1, 2, 3, 4 );
mod_table( %table, 1, 2, 3, 4 );

All I have to do is uncomment the next to last line and I get:

Useless use of modulus (%) in void context at - line 17.
Useless use of a constant in void context at - line 17.
Useless use of a constant in void context at - line 17.
Useless use of a constant in void context at - line 17.
Bareword "mod_table" not allowed while "strict subs" in use at - line 17.

It doesn't complain about the local sub, but it loses its mind over the imported one. On top of that despite the tests telling me that I've imported 'mod_table', strict is now confused that it is a bareword!

Not only that but despite the tests telling me that the prototypes are the same, I can't pass %table as a hashref to the imported sub. Not even if I use the conventional syntax, shown in the last line.

What I get is:

1..4
ok 1 - use TableMod;
ok 2 - main->can('mod_table')
ok 3 - prototype( \&mod_table_here ) = '\%@'
ok 4 - prototypes ARE the SAME!
$VAR1 = {
          'One' => '1'
        };
$VAR2 = 1;
$VAR3 = 2;
$VAR4 = 3;
$VAR5 = 4;
$VAR1 = 'One';
$VAR2 = '1';
$VAR3 = 1;
$VAR4 = 2;
$VAR5 = 3;
$VAR6 = 4;

Solution

  • Its because use_ok is being called at run-time. If you add the following then it all works fine:

     use TableMod 'mod_table';
    

    I normally only keep a single test file with use_ok in (normally 00-load.t or 00-use.t). I think Ovid may have written a blog post about this being a good practice?

    Update: Found Ovid's blog post I was referring to.

    /I3az/