17

通常,一个包的开头很简单

package Cat;
... #content
!0;

我刚刚发现从 perl 5.14 开始也有“块”语法。

package Cat {
    ... #content
}

大概是一样的。但可以肯定的是,有什么区别吗?

关于1;包文件末尾的。任何块的返回值,都被视为最后一个计算表达式的值。那么我可以1;在关闭之前放置}吗?为了require开心,有什么区别:

package Cat {
    ... #content
    1; 
}

package Cat {
    ... #content 
}
1;
4

5 回答 5

11

当然有区别。第二个变体有一个block

package声明为 subs 和 globals 设置当前命名空间。这通常是限定范围的,即范围以文件结尾或 eval 字符串结尾,或以封闭块结尾。

语法package NAME BLOCK只是语法

{ package NAME;
  ...;
}

甚至编译成相同的操作码。

虽然package声明在语法上是一个声明,但在语义上却不是真的;它只是设置编译时属性。因此,最后一个块的最后一条语句就是文件的最后一条语句,两者没有区别

package Foo;
1;

package Foo {
  1;
}

wrt。最后的声明。

我认为package BLOCK语法很有趣,主要是因为它看起来像class Foo {}其他语言。因为块限制了范围,这也使得使用适当范围的变量更容易。思考:

package Foo;
our $x = 1;
package main;
$::x = 42;
say $x;

输出: 1, 因为our在词法范围上是一样my的,只是声明了一个别名!这可以通过块语法来防止:

package Foo {
  our $x = 1;
}
package main {
  $::x = 42;
  say $x;
}

按预期工作(42),虽然strict不开心。

于 2013-07-05T09:34:30.667 回答
5
package Foo { ... }

相当于

{ package Foo; ... }

这与以下不同之处在于它创建了一个块

package Foo; ...

仅当您在文件中包含代码时,这才重要。


package Foo { ... }

等于

BEGIN { package Foo; ... }

我本来会喜欢这个的,但是那个提议没有被接受。


require(and do) 要求文件中评估的最后一个表达式返回真值。{ ... }评估为内部评估的最后一个值,因此以下内容很好:

package Foo { ...; 1 }

把它1;放在外面对我来说更有意义——它与文件而不是包有关——但这只是一种风格选择。

于 2013-07-05T11:12:51.627 回答
3

区别:) 如果您可以尝试在两个不同的代码片段下运行(只需将模块导入 perl 文件)

# perlscript.pl

use wblock;

wblock::wbmethod();

第一个没有块的代码片段,wblock.pm

package wblock1;
my $a =10;
sub wbmethod1{
        print "in wb $a";
}

package wblock;

sub wbmethod{
        print "in wb1 $a";
}
1;

其次是wblock.pm

package wblock1 {
my $a =10;
sub wbmethod1{
        print "in wb $a";
}
1;
}

package wblock {
sub wbmethod{
        print "in wb1 $a";
}
1;
}

现在您可能已经看到不同之处在于,当我们使用 BLOCK 时,变量$a不可用于包。wblock但是没有 BLOCK 我们可以$a从其他包中使用,因为它的范围是文件。

更多来自perldoc本身的说法:

也就是说,没有 BLOCK 的表单在当前作用域的末尾都有效,就像 my、state 和 our 运算符一样。

于 2013-07-05T09:24:33.340 回答
1

有区别,但前提是您进行难以维护的编程。特别是,如果您跨包使用my变量。Perl 的约定是每个文件只有一个包,而整个包在一个文件中。

于 2013-07-05T14:52:54.287 回答
1

还有一个其他答案没有给出的区别,这可能有助于解释为什么有两个。

package Foo;
sub bar { ... }

在 Perl 5 中总是这样做的package BLOCK

package Foo {
  sub bar { ... }
}

仅在 perl 5.14 中添加。

主要区别在于后一种形式更简洁,但仅从 5.14 开始有效;前一种形式将适用于旧版本。更整洁的形式主要是为了视觉整洁;它没有任何值得担心的语​​义差异。

于 2013-07-15T01:37:49.807 回答