Perl类方法和对象方法

时间:2013-12-12 02:35:20

标签: perl class object

在学习其他语言时,类方法和对象方法之间通常存在差异。

我知道,在Perl中,班级很弱。类方法和对象方法之间是否也有区别?

我知道最常用的类方法可能是类的new方法。在Perl中,我可以使用包名称调用所有方法,但不能调用包的对象。那是为什么?

2 个答案:

答案 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,它不仅为您提供方法签名,还为classrole等提供关键字。在这里拉扯它的特殊原因是,由于它支持“多方法”,你甚至可以创建一个具有相同名称的类方法和对象方法!

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);