在学习其他语言时,类方法和对象方法之间通常存在差异。
我知道,在Perl中,班级很弱。类方法和对象方法之间是否也有区别?
我知道最常用的类方法可能是类的new
方法。在Perl中,我可以使用包名称调用所有方法,但不能调用包的对象。那是为什么?
答案 0 :(得分:12)
perlobj
man page在这里很有用:
当您调用方法时,箭头左侧的东西将作为方法的第一个参数传递。这意味着当我们调用
Critter->new()
时,new()
方法接收字符串"Critter"
作为其第一个参数。当我们调用$fred->speak()
时,$fred
变量将作为第一个参数传递给speak()
。
换句话说,Perl并没有在类方法和实例方法之间做出明确的区分。它们被作为方法的第一个参数传递的内容区分开来,并且如果某些方法实际上没有关心作为第一个参数传递的内容,那么你可以欺骗并以“错误”方式调用它们。 / p>
Perl不在乎。它通常不会。
答案 1 :(得分:5)
@qwrrty的回答是对这种情况的一个很好的解释,但是从评论中我得到的印象是即使Perl在对象和类方法之间没什么区别,@ JackXu也会喜欢这样的区别。 / p>如果你想做出这样的区分,那么解决方法是检查
$_[0]
以查看它是一个对象还是一个字符串,并且表现得恰当(例如,如果用类调用对象方法则抛出异常name作为第一个参数)。CPAN上有各种方法签名模块,可以很容易地实现这一点:
package Foo; method xxx (Object $self: Int $x) { ...; } Foo->xxx(1); # throws an error because "Foo" is not an object
我将为这类事情提供自己的解决方案 - Moops,它不仅为您提供方法签名,还为
class
,role
等提供关键字。在这里拉扯它的特殊原因是,由于它支持“多方法”,你甚至可以创建一个具有相同名称的类方法和对象方法!use Moops; class Foo { multi method xxx (ClassName $class: Int $x) { say "CLASS METHOD - value $x"; } multi method xxx (Object $self: Int $x) { say "OBJECT METHOD - value $x"; } } Foo->xxx(1); my $foo = Foo->new; $foo->xxx(2);