为什么在Perl 5.14中不允许使用“use”,比如“use strict;”?

12

我正试图使用我被指导要遵循的良好/适当/安全的Perl代码惯例来编写我的"Hello, World!"程序:

use strict;
use warnings;

我已经使用(Strawberry) Perl 5.12 在我的主Windows 7操作系统上创建并成功运行了以下“Hello World”程序:

!#/usr/bin/perl
use strict;
use warnings;

print "Hello, World!\n";

正如预期收到的那样,我得到了"Hello, World!"

让我感到非常奇怪的是,在我的虚拟化Linux Mint 14操作系统上通过终端运行相同程序,使用Perl 5.14时,产生了以下错误:

"use" not allowed in expression at /PATH/hello_world.pl line 2, at end of line
syntax error at /PATH/hello_world.pl line 2, near "use strict"
BEGIN not safe after errors--compilation aborted at /PATH/hello_world.pl line 3.

后来我创作了其他的“Hello World”程序,没有使用use strict;use warnings;这两行代码,还有一个版本是用了-w参数,我在一些教程中看到过,它会打开警告提示功能(如果我没记错的话)。

我的另外两个版本都正常工作,它们都产生了我期望的结果:

Hello, World!

我不能确定的是,在Perl 5.14及更高版本中,是否需要在程序中使用use语句,或者只需在第一行末尾写上-w即可。

我希望在所有的Perl程序中都能使用统一的头部,无论它们是Windows还是Linux、Perl 5.12或5.14或其他版本。


5
你将其FTP到了你的Linux系统吗?你使用了文本模式吗? - Edward Thomson
4
“使用”是绝对允许的 :) 问题在于别的地方——也许正如Edward Thomson所暗示的那样,当你从一台电脑通过FTP传输文件到另一台电脑时,你的源文件出现了损坏。 - paulsm4
没有使用FTP。使用带有Linux Mint 14的VirtualBox。不使用文本模式。 - bc1984adam
我创建了一张屏幕截图,展示了我使用不同版本的“Hello, World!”程序进行尝试的情况。链接在这里:link - bc1984adam
2个回答

17
您的图片显示,您所有的脚本都以!#/usr/bin/perl开头。这是错误的。它不是有效的 she-bang 行,它被解释为否定符号 ! 后面跟着一个注释 #。解析将继续进行,并且对于 script1.pl,perl 将执行 ! print "Hello world.\n";。这将打印出 Hello world 并否定 print 的结果...虽然没有什么用,但是是有效的 perl。
script2.pl 中,perl 看到了 ! use strict;,这是一个编译时错误,因此 perl 失败并报告了行 use strict; 的错误。
因此,如果您使用正确的 she-bang 行,所有三个脚本都将按预期工作。
(编辑:添加了测试脚本)

script1.pl

!#/usr/bin/perl

print "Hello world.\n" ;

调用 perl script1.pl 会得到:

Hello world.

script2.pl

!#/usr/bin/perl

use strict;
use warnings ;

print "Hello world.\n" ;

呼叫 perl script2.pl 会得到:
"use" not allowed in expression at script2.pl line 3, at end of line
syntax error at script2.pl line 3, near "use strict "
BEGIN not safe after errors--compilation aborted at script2.pl line 4.

使用正确的语法 script3.pl
#!/usr/bin/perl

use strict ;
use warnings ;

print "Hello world.\n" ;

调用 perl script3.pl 的结果是:
Hello world.

为什么要踩?这就是问题的原因。我可以验证它。 - dgw
3
你的 script1.pl 没有忽略错误的 shebang 行,因为当你写 !# 时,显然它不是 shebang 行。它是 !(非)运算符,后面跟着一个注释。所以这与写 !print 是相同的:反转 print 语句的返回值 —— 当然这个值无论如何都会被忽略。而在 script2.pl 中,它正在做 !use,这是没有意义的,因为 use 是编译时的结构,而不是运行时的函数。 - Smylers
@Smylers 你是对的,我改变了我的答案,给出了正确的失败原因。谢谢。 - dgw
谢谢你的帮助!我感觉好多了,知道我只是犯了一个简单的错误! - bc1984adam

9

您做了类似于以下的操作:

use warnings
use strict;

替代

use warnings;
use strict;

实际上,我认为这可能是行尾问题。您在应该使用CR LF的地方使用了LF,或者反之。我曾经见过这种情况导致Perl认为代码从shebang行的一半开始(例如perl use strict;)。


如其他地方所述,您发布的代码与您使用的代码不同。您实际使用的是

!use strict;

由于错误的shebang行导致问题。
!#/u...         # Negation followed by a comment

应该是

#!/u...         # Shebang

有没有办法通过在shebang行末尾添加额外的换行符来测试它?我能使用“\n”吗? - bc1984adam
我在shebang行的末尾测试了-w,也测试了"\n",但是两者都没有改变输出/错误。我找到了以下文档,其中讨论了如何处理Windows和Linux之间的CR/LF问题。同样,我尝试了警告模式,它建议您实施以防止刚才提到的问题发生,但是没有任何变化。我不明白为什么在新的Linux安装上编写和运行这些基本程序会出现CR LF问题。我根本没有使用FTP。 - bc1984adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接