4

How would I solve the following error "Undefined subroutine &main::resetCounters called at"? The subroutine has been prototyped but still Perl complains. The following code is what I am having issues with:

#!/usr/bin/perl
use strict;
use warnings;

...

sub reportStats();
sub resetCounters();  #HERE IS THE PROTOTYPE
sub getUpperBusTimeStampAndBatchSize($);
sub toMs($);
sub tibTimeToMs();
sub calcStdDev();

...

print "\nTimeStamp  TPS   MPS    MaxBat  AvgBat  MaxLat  AvgLat  StdLat  >5ms    %>5ms\n";
resetCounters();  #THIS IS THE LINE CONTAINING THE ERROR

...

sub resetCounters()
# -----------------------------------------------------------
# resets all metrics counters
# -----------------------------------------------------------
{
  $tps = 0;
  $mps = 0;
  $batch = 0;
  $maxBatch = 0;
  $avgBatch = 0;
  $latency = 0;
  $latencySum = 0;
  $maxLatency = 0;
  $avgLatency = 0;
  $overThreshold = 0;
  $percentOver = 0;
  $currentSecond = $second;
  @latencies = ();
}
Matt Pascoe
  • 8,651
  • 17
  • 42
  • 48
  • swag --- are you missing the module with that contains the missing functionality? Please post a complete minimal test case that reproduces the error. – David Harris Jan 05 '12 at 20:03
  • 1
    What version of Perl are you using? A minimal test case works for me under 5.14.2. – CanSpice Jan 05 '12 at 20:09
  • Your code seems to work here. Are you sure resetCounters isn't being undefined somewhere? I'd be tempted to jump into the Perl debugger and finding out when resetCounters gets undefined. – Rohaq Jan 05 '12 at 20:18
  • 4
    The prototypes are completely unnecessary and [Considered Harmful](http://stackoverflow.com/questions/297034). You are also calling the sub with parentheses so even the forward declaration is unnecessary. – mob Jan 05 '12 at 21:38
  • Maybe there's an `__END__` token inside that third yada operator. Or unterminated string, regular expression, pod, etc. – mob Jan 05 '12 at 21:39

3 Answers3

2

The prototype is not required except when the subroutine has parentheses. If you do not include parentheses then there is no issue. The code would look like:

#!/usr/bin/perl
use strict;
use warnings;

...

print "\nTimeStamp  TPS   MPS    MaxBat  AvgBat  MaxLat  AvgLat  StdLat  >5ms    %>5ms\n";
resetCounters();

...

sub resetCounters #No parentheses
# -----------------------------------------------------------
# Resets all metrics counters
# -----------------------------------------------------------
{
    $tps = 0;
    $mps = 0;
    $batch = 0;
    $maxBatch = 0;
    $avgBatch = 0;
    $latency = 0;
    $latencySum = 0;
    $maxLatency = 0;
    $avgLatency = 0;
    $overThreshold = 0;
    $percentOver = 0;
    $currentSecond = $second;
    @latencies = ();
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matt Pascoe
  • 8,651
  • 17
  • 42
  • 48
1

I can't say for sure that this is the problem but you might look into the subs pragma for predeclaring your functions.

A quick one off ...

#!/usr/bin/env perl

use strict;
use warnings;

use subs "myclear";

my $var = 1;

myclear;

print $var;

sub myclear () {
  $var = 0;
}

Further, since this kind of procedural command is likely to happen as its own statement, it really doesn't need a null prototype, or any prototype at all.

#!/usr/bin/env perl

use strict;
use warnings;

use subs "myclear";

my $var = 1;

myclear;

print $var;

sub myclear {
  $var = 0;
}
Joel Berger
  • 20,180
  • 5
  • 49
  • 104
-1

That's bizarre.

I'd be most inclined to believe that something is failing silently before resetCounters is being defined, but then, "strict" should prevent that.

Have you tried using ampersand?

&resetCounters();

[EDIT]

The only place I've seen something similar is with CARP.

Something in the script doesn't compile, so the BEGIN statement doesn't compile and you end up getting an error from it, rather than from the code that failed.

use CGI::Carp qw(fatalsToBrowser set_message);

# HTML-format error reporter.  Comment out if script wont compile 
BEGIN
    { set_message( \&handle_errors ); }
mmrtnt
  • 382
  • 1
  • 8
  • If it works with ampersand but fails without it, there's still a problem. In other words, adding the `&` is a workaround or diagnostic, not a solution. – Keith Thompson Jan 05 '12 at 20:37