Почему вы должны поставить 1; в конце модуля Perl 5?

Почему все модули Perl 5 должны заканчиваться 1; ?

18
задан Chas. Owens 31 August 2010 в 12:19
поделиться

1 ответ

Это потому, что use Module LIST; эквивалентно BEGIN { require Module; Модуль->импорт(СПИСОК); } (см. perldoc -f use)

В частности, require Module; можно реализовать с помощью следующего фрагмента кода (из perldoc -f require):

sub require {
  my ($filename) = @_;
  if (exists $INC{$filename}) {
    return 1 if $INC{$filename};
    die "Compilation failed in require";
  }
  my ($realfilename,$result);
  ITER: {
    foreach $prefix (@INC) {
      $realfilename = "$prefix/$filename";
      if (-f $realfilename) {
        $INC{$filename} = $realfilename;
        $result = do $realfilename; ## HERE
        last ITER;
      }
    }
    die "Can't find $filename in \@INC";
  }
  if ($@) {
    $INC{$filename} = undef;
    die $@;
  } elsif (!$result) { ## AND HERE
    delete $INC{$filename};
    die "$filename did not return true value";
  } else {
    return $result;
  }
}

Видите do $realfilename? Посмотрите на perldoc -f do, и вы увидите, что это в значительной степени эквивалент eval system("cat $realfilename"), что в основном означает глотание файла в и оцените его.

Глядя на perldoc -f eval, вы получите: «В обеих формах возвращаемое значение является значением последнего выражения, вычисленного внутри мини-программы». То есть последний оператор в файле.

Стоит отметить, что если последнее «оператор» является объявлением подпрограммы, это не является истинным значением:

$ perl -le'$r = eval "sub a {1}"; print $r ? "true" : "false"'
false

В то время как 1; после него:

$ perl -le'$r = eval "sub a {1} 1"; print $r ? "true" : "false"'
true

Глядя снова на sub require выше, и зная, что делает require и do, $result, что do $ realfilename возвращает действительно последний оператор evaled из файла, который действительно является последним оператором в файле.

Если такой последний оператор не является истинным значением, то ## AND HERE elsif(), который я выделил, будет вызываться, а require умрет, поскольку модуль не возвращает истинное значение. Модуль use также умрет, так как он выполняет require за кулисами.

Короче говоря, не имеет значения, чем вы заканчиваете файл, если это значение понимается perl как true. Образцы в дикой природе (CPAN) включают 1;, хотя некоторые в наши дни предпочитают заканчивать свои файлы на 1 (без пропущенной точки с запятой), а другие просто странно используют такие вещи, как ' 0, но true'; или 'supercalifragilisticexpiralidous';, все из которых Perl анализирует как "истинные" значения.

Надеюсь, вышесказанное вас удовлетворило ;)

Удачного взлома!

7
ответ дан 30 November 2019 в 07:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: