Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

prototype

perl

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);

like image 452
petitLynx Avatar asked Feb 04 '19 15:02

petitLynx


Video Answer


2 Answers

Simple: forward declaration

sub pv($);
sub pv($) {
like image 174
Stefan Becker Avatar answered Oct 11 '22 17:10

Stefan Becker


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.

like image 44
Grinnz Avatar answered Oct 11 '22 18:10

Grinnz