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

Nem*_*emo 17 perl

通常,包只是简单地开始

package Cat;
... #content
!0;
Run Code Online (Sandbox Code Playgroud)

我刚刚发现,从perl 5.14开始,还有"块"语法.

package Cat {
    ... #content
}
Run Code Online (Sandbox Code Playgroud)

它可能是一样的.但是可以肯定的是,有什么区别吗?

关于1;包文件的末尾.任何块的返回值都被视为最后一个计算表达式的值.所以我可以1;在结束之前把它放进去}吗?为了require开心,两者之间有什么区别:

package Cat {
    ... #content
    1; 
}
Run Code Online (Sandbox Code Playgroud)

package Cat {
    ... #content 
}
1;
Run Code Online (Sandbox Code Playgroud)

amo*_*mon 11

当然有区别.第二个变体有一个.

一个package声明设置了潜艇和全局当前命名空间.这通常是作用域,即范围以文件末尾或eval字符串结尾,或以封闭块结束.

package NAME BLOCK语法只是语法糖

{ package NAME;
  ...;
}
Run Code Online (Sandbox Code Playgroud)

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

虽然package声明在语法上是一个声明,但这在语义上并不正确; 它只是设置编译时属性.因此,最后一个块的最后一个语句是文件的最后一个语句,并且没有区别

package Foo;
1;
Run Code Online (Sandbox Code Playgroud)

package Foo {
  1;
}
Run Code Online (Sandbox Code Playgroud)

WRT.最后一句话.

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

package Foo;
our $x = 1;
package main;
$::x = 42;
say $x;
Run Code Online (Sandbox Code Playgroud)

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

package Foo {
  our $x = 1;
}
package main {
  $::x = 42;
  say $x;
}
Run Code Online (Sandbox Code Playgroud)

按预期工作(42),虽然strict不高兴.


ike*_*ami 5

package Foo { ... }
Run Code Online (Sandbox Code Playgroud)

相当于

{ package Foo; ... }
Run Code Online (Sandbox Code Playgroud)

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

package Foo; ...
Run Code Online (Sandbox Code Playgroud)

这只有在文件中包含以下代码时才有意义.


package Foo { ... }
Run Code Online (Sandbox Code Playgroud)

等于

BEGIN { package Foo; ... }
Run Code Online (Sandbox Code Playgroud)

我本来希望这样,但该提议未被接受.


require(和do)要求在文件中计算的最后一个表达式返回一个真值.{ ... }计算到内部评估的最后一个值,因此以下情况很好:

package Foo { ...; 1 }
Run Code Online (Sandbox Code Playgroud)

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