“标准”和块包装声明之间有什么区别吗?

时间:2013-07-05 08:07:32

标签: perl

通常,包只是以

开头
package Cat;
... #content
!0;

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

package Cat {
    ... #content
}

可能是一样的。但是,可以肯定的是,是否存在任何差异?

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

package Cat {
    ... #content
    1; 
}

package Cat {
    ... #content 
}
1;

5 个答案:

答案 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之后起作用;前一个表单将恢复到旧版本。整体形式的添加主要是为了视觉整洁;它没有任何值得担心的语​​义差异。