Perl:在Perl中,“-”代表什么意思?

3
在参数中,'-'代表选项未设置或无效。
$cgi->start_html(-title => uc($color), -BGCOLOR => $color);

我知道它在哈希类型中使用,但这是一个子参数。所以这让我感到困惑,我搜索了很长时间。


2
如果你有选择的话,请不要使用CGI。基于PSGI/Plack的东西会让你的生活变得轻松许多。请私信我,如果有任何疑问。 - Dave Cross
4个回答

4
每当你在Perl中遇到语法混乱的情况,一个方便的工具是-MO=Deparse选项。这会导致Perl检查脚本的语法并以规范化的形式输出脚本,而不是执行它。
所以,如果我执行
perl -MO=Deparse -e '$cgi->start_html(-title => uc($color), -BGCOLOR => $color);'

我得到了一个结果:

$cgi->start_html(-'title', uc $color, -'BGCOLOR', $color);
-e syntax OK

这里有三个不同之处:
  1. titleBGCOLOR 中添加了引号。
  2. => 运算符更改为逗号。
  3. uc($color) 消失了括号。
前两个是 =>("fat comma") 运算符的正常效果:它相当于逗号,只是如果左边的东西是标识符(以字母或下划线开头,只包含字母数字字符和下划线),那个标识符就变成了带引号的字符串。
而在 uc 后面的括号在这种情况下并不是严格必要的,因为内置函数 uc 原型化为接受 0 或 1 个参数。
但现在我们有了-'title'和-'BGCOLOR',那么字符串的负数是什么?查看perldoc perlop,我们可以看到一元减遵循以下规则:
  1. 如果操作数是数字或数字的字符串表示形式,则执行算术否定。
  2. 否则,如果字符串以'+'或'-'开头,则只将字符串的第一个字符切换为相反的符号。
  3. 否则,如果字符串以字母开头,则在字符串开头添加'-'
  4. 否则,尝试将字符串转换为数字,如果启用了警告,则可能会打印警告,然后执行算术否定。
这里我们是case 3,所以-'title'是'-title',-'BGCOLOR'是'-BGCOLOR'。
因此,可以推测 start_html 方法期望一个由键值对组成的参数列表,且键字符串应以连字符开头。 (它可能会使用这些参数来创建哈希表,类似于 my %options = @_;。)这有点绕弯子,而且如果您尝试传递像 -3zzz => $value 这样的内容,结果可能令人困惑。所以我个人会在这里添加明确的引号来表明正在传递什么,但仍然使用大逗号来强调参数应该是键/值对。
$cgi->start_html('-title' => uc($color), '-BGCOLOR' => $color);

为什么关键字符串以连字符开头?我何时使用连字符?没有连字符的关键字符串有什么区别? - tezr
1
什么也没有。它们只是字符串。 - Sobrique

3

这里它没有影响,只是被看作字符串的一部分。我猜测 CGI.pm 的原作者想要让选项看起来更像命令行选项,但我认为这是一个很糟糕的想法。


我同意这不是最好的想法,但这并不罕见,其他模块也使用这种约定。第一次看到它时,我和OP有同样的问题,想知道为什么他们只使用一个破折号,而不是两个(如--real-long-options)。我认为如果没有'--quoting',它就无法正常工作。 - PerlDuck
@PerlDuck:我不认为我使用任何其他模块使用这种约定(当然,这些天我也不经常使用CGI.pm)。 - Dave Cross

1
这是一个字符串字面量,就像“-title”或“-BGCOLOR”一样。

1

perldoc perlop:

[一元运算符 "-" ...] 如果操作数是一个标识符,则返回一个由减号和标识符组成的字符串。否则,如果字符串以加号或减号开头,则返回一个以相反符号开头的字符串。

换句话说,-"foo" 就是 "-foo"

=> 运算符(有时发音为 "fat comma")是逗号的同义词,除了它会导致其左侧的单词被解释为一个字符串,如果它以字母或下划线开头,并且仅由字母、数字和下划线组成。

换句话说,foo => 42 就是 "foo", 42

综上所述,-title => uc($color) 就是 "-title", uc($color)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接