通常,包只是以
开头package Cat;
... #content
!0;
我刚刚发现,从perl 5.14开始,还有“块”语法。
package Cat {
... #content
}
可能是一样的。但是,可以肯定的是,是否存在任何差异?
关于包文件末尾的1;
。任何块的返回值都被视为最后一个计算表达式的值。那么我可以在结束1;
之前放置}
吗?为了让require
满意,之间有什么区别:
package Cat {
... #content
1;
}
和
package Cat {
... #content
}
1;
答案 0 :(得分:11)
当然有区别。第二个变体有一个块。
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
不满意。
答案 1 :(得分:5)
package Foo { ... }
相当于
{ package Foo; ... }
与以下内容的不同之处在于它创建了一个块
package Foo; ...
这只有在文件中包含以下代码时才有意义。
package Foo { ... }
不等于
BEGIN { package Foo; ... }
我本来希望如此,但该提案未被接受。
require
(和do
)要求文件中计算的最后一个表达式返回一个真值。 { ... }
计算到内部评估的最后一个值,因此以下情况很好:
package Foo { ...; 1 }
将1;
放在外面对我来说更有意义 - 它与文件而不是包相关 - 但这只是一种风格选择。
答案 2 :(得分: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的表单可以在结束时使用 当前范围,就像我,州和我们的运营商一样。
答案 3 :(得分:1)
存在差异,但前提是您正在进行难以维护的编程。特别是,如果您在包中使用my
变量。 Perl的约定是每个文件只有一个包,整个包在一个文件中。
答案 4 :(得分:1)
其他答案没有给出另外一个区别,这可能有助于解释为什么有两个答案。
package Foo;
sub bar { ... }
始终是在Perl 5中执行此操作的方法。
的package BLOCK
语法
package Foo {
sub bar { ... }
}
仅在perl 5.14中添加。
然后,主要区别在于后者的形式更整洁,但仅在5.14之后起作用;前一个表单将恢复到旧版本。整体形式的添加主要是为了视觉整洁;它没有任何值得担心的语义差异。