0

I am working on a factorial function in Perl. The code below gives me the error Can't return outside a subroutine.

factorial {
    my $n = $ARGV[0];
    if( $n <= 1 ){
        return 1;  # ----- Error Here -----
    }
    else {
        return $n * factorial($n - 1);
    }
}

I believe my if statement is still inside the subroutine. What is causing the error?

Mint.K
  • 849
  • 1
  • 11
  • 27
  • 7
    You define a subroutine by `sub factorial { ... }`. Without the `sub` keyword it's something else, and not a subroutine – zdim Mar 06 '17 at 06:24
  • Call function in the main `factorial();` – ssr1012 Mar 06 '17 at 06:57
  • Also note, that `$ARGV[0]` is the first command line argument to your program, not the first parameter to your subroutine (that's in `$_[0]`). – Dave Cross Mar 06 '17 at 11:18

1 Answers1

8

Indirect method notation strikes again![1]

factorial { ... }

is being parsed as

(do { ... })->factorial

The problem is that you are missing the sub keyword at the start of the sub's declaration. Replace

factorial { ... }

with

sub factorial { ... }

Also, subroutine arguments are provided in @_, not @ARGV, so

my $n = $ARGV[0];

should be

my $n = $_[0];
  -or-
my $n = shift;
  -or-
my ($n) = @_;

Finally, using a recursive approach is very inefficient. Sub calls are rather expensive. The following is much faster:

sub factorial {
    my $n = shift;
    my $acc = 1;
    $acc *= $_ for 2..$n;
    return $acc;
}

  1. It's existence causes many errors from being caught when they should be, as you can see in this magnificent example.
Community
  • 1
  • 1
ikegami
  • 367,544
  • 15
  • 269
  • 518