当实例方法通过“$ self”引用相互调用时,在Perl中这是一个很好的做法吗?

时间:2011-06-29 13:33:26

标签: perl oop

Perl中的实例方法应该像这样相互调用:

package BlaBla;

sub foo {
    my($self) = @_;
    #do something awesome;
}

sub bar {
    my($self) = @_;
    foo();
}

或者像这样:

package BlaBla;

sub foo {
    my($self) = @_;
    #do something awesome
}

sub bar {
    my($self) = @_;
    $self->foo();
}

谢谢大家的时间。

5 个答案:

答案 0 :(得分:15)

是的,你应该包含$self - 否则,多态将无法工作,因为每个方法都会在自己的包中查找所有调用,即使它们在子类中被覆盖也是如此。更糟糕的是,如果引用的方法是从父类继承而在当前子类中重写,则程序将die,因为它在该包中不存在。即使你确实记得试图通过传递$self作为第一个参数来伪造Perl的OO机制。

答案 1 :(得分:9)

如果foo()是一个可以从其他地方调用的方法,你当然应该把它作为一个方法来调用,否则从你继承的类将无法覆盖它,你将强制你的foo()检查它是以方式方式还是以函数方式调用。

另一方面,如果foo()只是你的一些方法使用的一些帮助代码,并且非常特定于你的类的实现,那么你可以直接调用它,但是应该真的总是调用它直接,并且可能希望通过在其名称前加下划线来将其标记为类可用的私有函数:_foo()。

答案 2 :(得分:8)

假设您在$self中的某处使用foo(),第一个将无效,因为它没有传递任何参数。你可以调用foo($self),但你几乎肯定会更好地使用实际的方法调用语法,而不是将Perl的OO功能抛出窗口而只是将foo()视为一个恰好调用它的函数参数“$self”。

答案 3 :(得分:4)

是的,实例方法应该使用$self相互调用 - 否则,在某些情况下,您需要检查方法的参数并确定是否在$self上调用它,这将使你的代码无缘无故地变得更加混乱。

答案 4 :(得分:3)

第一种方法不会按照书面形式运作。

sub bar {
  my($self) = @_;
  foo();
}

在这里,您通过foo语句显式调用foo();作为没有参数的函数。这将构造一个空的本地@_数组。 foo中的第一个语句将$self提取为此本地@_的第一个元素,因此$self未使用此机制进行定义。

您需要将$self作为参数传递给foo。有(至少)五种方法可以做到这一点:

  1. 箭头表示法:通过foo
  2. 调用$self->foo();
  3. 间接表示法:通过foo
  4. 调用foo $self;
  5. 正常子程序调用:通过foo
  6. 调用foo($self);
  7. 隐含参数:通过foo调用foo $self;此选项仅在foo预先声明了函数原型时使用。
  8. 不要构造本地@_数组。让foo搭载bar的{​​{1}}数组。通过@_调用foo请注意,此调用中没有括号。
  9. 关于选项#5:确实存在。不要使用它。它会让你陷入麻烦。

    当foo采用其他参数时,#2和#4之间的区别变得明显。间接符号变为(例如)&foo;而隐含形式变为foo $self 42;现在强烈建议不要使用间接符号(选项2)。也不鼓励选项3和4与方法一起使用。

    留下选项#1。尽管箭头符号只是语法糖,但对读者来说意味着很多。使用它。