【问题标题】:Why do you have to put a 1; at the end of a Perl 5 module?为什么一定要放1;在 Perl 5 模块的末尾?
【发布时间】:2023-03-15 00:57:01
【问题描述】:

为什么所有 Perl 5 模块都必须以 1; 结尾?

【问题讨论】:

标签: perl module


【解决方案1】:

Perl 模块必须以真值结束,否则它被认为不是 已加载。按照惯例,这个值通常是 1,尽管它可以是 任何真值。一个模块可以以 false 结尾来表示失败,但是 这很少使用,它会改为 die() (退出并出现错误)。

来源:wiki

【讨论】:

  • 我已经看到 'false'; 以前用作真实值... :)
  • Dominus 曾经quipped,“我很少使用……'Cogito ergo sum';,众所周知,这在所有可能的宇宙中都是不言而喻的。这确保了最大的便携性。”
  • 这没有回答问题:为什么模块必须以真值结尾?
【解决方案2】:

这是因为use Module LIST; 等价于BEGIN { require Module; Module->import( LIST ); }(参见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,并了解requiredo 的作用,do $realfilename 返回的$result 确实是文件中evaled 的最后一条语句,这确实是文件中的最后一条语句。

如果最后一个语句不是真值,我突出显示的## AND HERE elsif() 将被调用,而require 将因为模块不返回真值而死掉。 use Module 也会死掉,因为它在幕后做 require

长话短说,文件以什么结尾并不重要,只要它是被 perl 理解为 true 的值。野生样本 (CPAN) 包括 1;,尽管现在有些人宁愿以 1 结束他们的文件(没有丢失分号),而其他人只是奇怪地使用像 '0 but true';'supercalifragilisticexpiralidous'; 这样的东西,所有这些都被解析作为 Perl 的“真实”值。

希望以上内容能让您满意;)

黑客愉快!

【讨论】:

    猜你喜欢
    • 2010-11-30
    • 2017-03-28
    • 2012-12-18
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 2020-11-18
    • 1970-01-01
    相关资源
    最近更新 更多