Todd Chester has asked for the wisdom of the Perl Monks concerning the following question:

Bummer: Net::FTP's "rmdir recurse" is junk.

What are the subroutine rules on calling myself?
sub RmdirAndLoop ( $ ) { my $Target = $_[0]; # directory to remove # print "Target = <$Target>\n"; print "Pruning <$Target>. This may take a while...\n"; if ( $ftp->rmdir ( "$Target", 1 ) ) { print " $Target deleted successfully\n"; } else { for my $Target2 ( @ { $ftp->ls ( "$Target/*" ) } ) { RmdirAndLoop ( $Target2 ); # < ---- This is line 266 } } print "\n"; }

Error: main::RmdirAndLoop() called too early to check prototype at Matt.RotatorForCobianBackup.FTP.pl line 266 (#1)

Many thanks,
-T

Replies are listed 'Best First'.
Re: What are the rules on calling myself?
by haukex (Archbishop) on Feb 04, 2017 at 09:03 UTC

    Hi Todd Chester,

    Perl's prototypes are sometimes misunderstood to be something like function type signatures, but that's exactly not what they are. In Perl, Prototypes influence not only what subroutine arguments are accepted, but how the calls to those subroutines are parsed. They're not necessarily the best thing for validating subroutine arguments, and can sometimes lead to confusing code. I'd recommend Perl's prototypes primarily for cases where one wants to create functions whose syntax imitates Perl builtins.

    In your case, it's the "( $ )" immediately after sub RmdirAndLoop, which makes calls to RmdirAndLoop be parsed like a unary operator. Unless it is your intention to change how calls to RmdirAndLoop are parsed, as the AM said it's perfectly fine to remove the "( $ )" prototype, and if desired add code to check the arguments.

    Just for completeness, there is another way to get rid of the warning, from the bottom of the Prototypes doc:

    If a sub has both a PROTO and a BLOCK, the prototype is not applied until after the BLOCK is completely defined. This means that a recursive function with a prototype has to be predeclared for the prototype to take effect, like so:

    sub foo($$); sub foo($$) { foo 1, 2; }

    Hope this helps,
    -- Hauke D

      Perfect! Thank you!
Re: What are the rules on calling myself? (too early to check prototype)
by Anonymous Monk on Feb 04, 2017 at 08:23 UTC

    Where did you read about prototypes?

    Just delete the prototype, you dont need them

    For an explanation of the error message turn on diagnostics or use splain

      The error message came up when I ran the code.

      Line 266 is where I called myself.

      Do you know the subroutine rules on calling yourself?

      The goal is to loop through and the directorates until I get them all

      -T

        Hi,

        A prototype is the ($) part, delete that

        Also, do use diagnostics/splain and read more about it