petitLynx
petitLynx

Reputation: 61

How to declare function and use it recursively without "called too early to check prototype"

I have a generic and recursive function but why it is not authorized in perl

sub pv($) {
    my ($vars) = @_;
    if(ref($vars) eq 'SNMP::Varbind') {
        return $vars->tag() . (defined($vars->iid()) ? '.' . $vars->iid() : '');
    } elsif (ref($vars) eq 'SNMP::VarList') {
        return join(', ', map { pv($_) } @$vars);
    } elsif(ref($vars) eq 'ARRAY') {
        return join('.', @{$vars});
    } else {
        return $vars;
    }
}

This error code "pv() called too early to check prototype" for this line return join(', ', map { pv($_) } @$vars);

Upvotes: 6

Views: 678

Answers (2)

Grinnz
Grinnz

Reputation: 9231

On Perl 5.16+, you can use the current_sub feature:

use strict;
use warnings;
use feature 'current_sub';

sub pv($) {
  ...
  __SUB__->($_)
  ...
}

This is more useful when using anonymous subs, so that you don't create a memory cycle (as it would close over a reference to itself; this doesn't occur with named subs, since it just looks up the symbol).

Additionally, consider just not using a prototype. It's very likely that you don't need it, unless you know why you do; prototypes are for the parser, not the caller. Without the prototype, calling it with parentheses will be sufficient to delay the symbol lookup.

Upvotes: 2

Stefan Becker
Stefan Becker

Reputation: 5962

Simple: forward declaration

sub pv($);
sub pv($) {

Upvotes: 8

Related Questions