为什么在这个Perl示例中定义的sdf返回true?

Aft*_*ock 3 perl strict bareword

我在Perl中尝试过这个例子.有人可以解释为什么这是真的吗?

  if (defined sdf)  {   print "true";  }
Run Code Online (Sandbox Code Playgroud)

它打印true.

sdf可以是任何名称.

另外,如果定义了sdf函数并且它返回0,则它不会打印任何内容.

print (sdf); 不打印sdf字符串但是

if (sdf eq "sdf")
{
 print "true";
}
Run Code Online (Sandbox Code Playgroud)

打印真实.

如果sdf是一个字符串,则相关问题仍然存在.什么不是印刷品?

Sin*_*nür 10

sdf是一个赤字.

perl -Mstrict -e "print qq{defined\n} if defined sdf"
Run Code Online (Sandbox Code Playgroud)
Bareword "sdf" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

为了更多的乐趣,试试吧

perl -Mstrict -e "print sdf => qq{\n}"
Run Code Online (Sandbox Code Playgroud)

严格说明使用严格:

use strict的subs方面禁止将"bare words"解释为文本字符串.默认情况下,Perl标识符(字母,数字和下划线的序列,不是以数字开头,除非它是完全数字),否则不是内置关键字或以前看过的子例程定义被视为带引号的文本字符串:

@daynames = (sun, mon, tue, wed, thu, fri, sat);
Run Code Online (Sandbox Code Playgroud)

但是,这被认为是一种危险的做法,因为可能会导致模糊的错误:

@monthnames = (jan, feb, mar, apr, may, jun,
               jul, aug, sep, oct, nov, dec);
Run Code Online (Sandbox Code Playgroud)

你能发现这个bug吗?是的,第10个条目不是字符串'oct',而是内置oct()函数的调用,返回默认值的数字等效,$_视为八进制数.

更正:(谢谢@ysth)

E:\Home> perl -we "print sdf"
Unquoted string "sdf" may clash with future reserved word at -e line 1.
Name "main::sdf" used only once: possible typo at -e line 1.
print() on unopened filehandle sdf at -e line 1.

如果print在间接对象槽中提供了一个裸字,则将其作为要打印的文件句柄.由于没有提供其他参数,因此print默认为打印$_到文件句柄sdf.由于sdf尚未打开,它失败了.如果在没有警告的情况下运行此操作,则看不到任何输出.另请注意:

E:\Home> perl -MO=Deparse -e "print sdf"
print sdf $_;

作为对此观察的确认.另请注意:

E:\Home> perl -e "print asdfg, sadjkfsh"
No comma allowed after filehandle at -e line 1.
E:\Home> perl -e "print asdfg => sadjkfsh"
asdfgsadjkfsh

后者打印两个字符串,因为=>如果它们仅由'word'字符组成,则自动引用LHS上的字符串,删除第一个参数的文件句柄解释.

所有这些例子表明,使用裸字会带来许多惊喜.你应该use strict避免这种情况.


Tim*_*Tim 5

这是一个" 赤字 ".如果允许,则其值为"sdf",因此未定义.