2013-07-05 39 views
17

通常情况下,一个包开始只是作为“标准”和块封装声明有什么不同吗?

package Cat; 
... #content 
!0; 

我才发现,原来从perl的5.14开始有“块”的语法了。

package Cat { 
    ... #content 
} 

它可能是相同的。但可以肯定的是,有没有的区别?

而关于1;在包文件的末尾。任何块的返回值都被视为最后评估的表达式的值。那么我可以在}之前把1;?为了使require快乐,有什么区别:

package Cat { 
    ... #content 
    1; 
} 

package Cat { 
    ... #content 
} 
1; 
+0

我只是建议,如果'require'无论哪种方式都很快乐(没有差别),那么就'require'而言没有区别。你的意思是说通过自己尝试代码找到答案根本没有帮助吗? – doubleDown

+1

@Nemo'package NAME {...}'只是'{package NAME; ...}';他们是完全一样的东西。如果文件中的最后一个语句是一个块,那么块中的最后一个语句就是'require'将会得到的值。 – amon

+1

公平地说,你的问题没有提到你自己尝试过,没有发现任何区别,所以我建议你也许可以尝试它(第二部分)。既然你发现它是冒犯性的(尽管它不是我的意图),我会删除这个违规的评论。 – doubleDown

回答

11

当然是有区别的。第二个变体具有

A package声明设置subs和全局变量的当前名称空间。这是正常的范围,即范围以文件或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不开心。

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; 
} 

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

更多从自身perldoc说:

也就是说,没有一个BLOCK的形式是通过手术的 结束当前的范围,就像我的,状态和我们的运营商。

+0

你的意思是:“如果你有多个没有BLOCK的软件包,你不能单独使用1;每个软件包都会单独使用,你会得到错误的。”?你能发布导致错误的代码示例吗?我试过了,它似乎工作正常。 – doubleDown

+0

@doubleDown - 我认为你是对的。删除相同。 – 2013-07-05 12:24:49

+4

'1;'被添加到'* .pm'文件的末尾,以向Perl编译器指示该文件已正确加载。它与包无关。因此,应该只有一个'1;',它应该在文件的末尾。 – shawnhcorey

5
package Foo { ... } 

相当于

{ package Foo; ... } 

这是从它创建一个块

package Foo; ... 

这只事项如果你有文件在下面的代码如下不同。


package Foo { ... } 

相当于

BEGIN { package Foo; ... } 

我会喜欢这一点,但这一建议未被接受。


require(和do)要求在文件中最后计算的表达式返回一个真值。 { ... }计算结果为内评估的最后的值,所以下面是罚款:

package Foo { ...; 1 } 

在外面放置1;更有意义,我—它涉及到的文件,而不是包—但是这仅仅是一个风格的选择。

1

只有在您正在进行难以维护的编程时,才会有区别。特别是,如果您在软件包中使用my变量。 Perl的惯例是每个文件只有一个包,而整个包只有一个文件。

1

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

package Foo; 
sub bar { ... } 

始终是在Perl 5中完成它的方式。package BLOCK语法

package Foo { 
    sub bar { ... } 
} 

仅在perl 5.14处添加。

主要区别在于后者的形式较整洁,但只能在5.14以后才能使用;前一种形式将回到旧版本。整洁的形式主要用于视觉上的整洁;它没有任何值得担心的语​​义差异。

相关问题