capser
capser

Reputation: 2635

Perl compile time errors depending on the procedural order of subroutines

So I have this file:

casper_mint@casper-mint-dell ~/learn_perl_hard_way $ cat bettypage
foo foo foo foo foo foo foo
boo boo boo

And wanted to read it it and print it between 2 sub routines.

This kept throwing errors:

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

sub read_file {
    my $file = shift ;
    open (FILE, $file) || die  " Couldn't open $file";
    while (my $line = <FILE>) {
          read_line $line ;
    }
}

sub read_line {
    my @list = split " ", shift ;
    foreach my $word (@list) {
            print "$word\n";
    }
}

read_file(@ARGV) ;

casper_mint@casper-mint-dell ~/learn_perl_hard_way $ ./test_hash.pl bettypage
Can't locate object method "read_line" via package "foo foo foo foo foo foo foo" (perhaps you forgot to load "foo foo foo foo foo foo foo"?) at ./test_hash.pl line 13, <FILE> line 1.
casper_mint@casper-mint-dell ~/learn_perl_hard_way $

So I put the "read_line subroutine" before the "read_file subroutine" - since it depends on it, from a procedural point of view and it works just fine.

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

sub read_line {
    my @list = split " ", shift ;
    foreach my $word (@list) {
            print "$word\n";
    }
}

sub read_file {
    my $file = shift ;
    open (FILE, $file) || die  " Couldn't open $file";
    while (my $line = <FILE>) {
           read_line $line ;
           }
     }

read_file(@ARGV) ;

I know from working with bash that the subroutines usually has to come first in the code for it to work.

However, I thought that perl compiles the script and then executes it. And by compiling, I did not think that it would matter where the subroutine was located.

That by compiling everything before executing the subroutine would at least be available to be read it by the whole program. If perl compiles the whole script before executing it, why should the order of the subroutine matter - shouldn't the "read_line" subroutine be available to the "read_file" subroutine - regardless of where it is placed in the script?

Upvotes: 1

Views: 46

Answers (1)

elcaro
elcaro

Reputation: 2317

Unless predeclared, you need to call your subs with parenthesis, ie. read_line($line)

From perlsub

To call subroutines:

1.  NAME(LIST);    # & is optional with parentheses.
2.  NAME LIST;     # Parentheses optional if predeclared/imported.
3.  &NAME(LIST);   # Circumvent prototypes.
4.  &NAME;         # Makes current @_ visible to called subroutine.

But really, just get into the habit of always using parenthesis (option 1). Your code will thank you later with better readability and less surprises.

Upvotes: 4

Related Questions