Ошибки времени компиляции Perl в зависимости от процедурного порядка подпрограмм

Итак, у меня есть этот файл:

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

И хотел прочитать это и распечатать между двумя подпрограммами.

Это продолжало выдавать ошибки:

#!/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 $

Поэтому я поставил подпрограмму read_line перед подпрограммой read_file - поскольку она зависит от нее с процедурной точки зрения и работает нормально.

#!/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) ;

По работе с bash я знаю, что для работы подпрограммы обычно должны стоять на первом месте в коде.

Однако я думал, что perl компилирует сценарий, а затем выполняет его. И при компиляции я не думал, что будет иметь значение, где находится подпрограмма.

Что, скомпилировав все перед выполнением подпрограммы, по крайней мере, будет доступно для чтения всей программой. Если perl компилирует весь сценарий перед его выполнением, почему порядок подпрограммы должен иметь значение - не должна ли подпрограмма «read_line» быть доступной для подпрограммы «read_file» - независимо от того, где она находится в сценарии?


person capser    schedule 18.02.2016    source источник
comment
Обозначение косвенного метода - вот почему у нас не может быть хороших вещей :(   -  person ikegami    schedule 18.02.2016


Ответы (1)


Если не указано заранее, вам нужно называть свои подпрограммы круглыми скобками, т.е. read_line($line)

Из 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.

Но на самом деле просто возьмите за привычку всегда использовать круглые скобки (вариант 1). Ваш код поблагодарит вас позже лучшей удобочитаемостью и меньшим количеством сюрпризов.

person Joshua    schedule 18.02.2016
comment
круглые скобки = единственное число, круглые скобки = множественное число - person Matt Jacob; 18.02.2016