很多年前,我记得一位程序员同意这个:
new Some::Class; # bad! (but why?) Some::Class->new(); # good!
可悲的是现在我不记得他/他的理由.:(两个表单都将正常工作,即使构造函数实际上不存在于Some :: Class模块中,而是从某个父节点继承.
这些形式都不与Some :: Class :: new()相同,它们不会将类的名称作为构造函数的第一个参数传递 - 因此这种形式总是不正确的.
即使两个表单是等价的,我发现Some :: Class-> new()更加清晰,因为它遵循在模块上调用方法的标准约定,而在perl中,'new'方法不是special - 一个构造函数可以被称为任何东西,new()可以做任何事情(当然我们通常期望它是一个构造函数).
使用new Some::Class
称为"间接"方法调用,这很糟糕,因为它在语法中引入了一些歧义.
它失败的一个原因是你有一个对象的数组或散列.你可能会期待
dosomethingwith $hashref->{obj}
等于
$hashref->{obj}->dosomethingwith();
但它实际上解析为:
$hashref->dosomethingwith->{obj}
这可能不是你想要的.
另一个问题是,如果您的包中碰巧有一个与您尝试调用的方法同名的函数.例如,如果您use
导出函数的某个模块被调用了dosomethingwith
怎么办?在这种情况下,dosomethingwith $object
是模棱两可的,并可能导致令人费解的错误.
使用->
语法专门消除了这些问题,因为编译器始终清楚该方法以及您希望该方法操作的内容.
有关其缺陷的解释,请参阅perlobj文档中的间接对象语法.freido的答案涵盖其中一个(虽然我倾向于避免使用我的函数调用的明确的parens).
Larry曾经开玩笑说它是为了让C++感到高兴new
,尽管人们会告诉你不要使用它,但你可能一直都在这样做.考虑一下:
print FH "Some message";
你有没有想过我的文件句柄后面没有逗号?并且在间接对象表示法中的类名后面没有逗号?这就是这里发生的事情.您可以将其重写为print上的方法调用:
FH->print( "Some message" );
print
如果你做错了,你可能会遇到一些奇怪的事.在显式文件句柄后面放一个逗号会将其转换为参数:
print FH, "some message"; # GLOB(0xDEADBEEF)some message
可悲的是,我们在Perl中有这种愚蠢.并非所有进入语法的东西都是最好的主意,但是当你从众多来源中获取灵感时,就会发生这种情况.一些想法必须是坏的.