Why doesn't Perl's SUPER call use the arro

2019-06-15 02:40发布

问题:

I noticed that when you call a superclass's methods, you need to do something like this :

my $self = $class->SUPER::new();

Why isn't that:

my $self = $class->SUPER->new();

回答1:

I suspect because $class->SUPER->new() would normally be the same as $class->SUPER()->new(). But there isn't a $class->SUPER() function, and its not clear what that would return.

On the other hand, $class->Foo::Bar has always been a valid way to call a method directly by full name, so making a special package-like thing — SUPER — fits in better. (I suspect that you could actually implement SUPER as a package, and maybe it historically was, I don't know)

PS: Take a look at the mro package, and $self->next::method. Also, take a look at Moose if you're going to do serious OO work in Perl.



回答2:

In short, SUPER isn't a method. It's a virtual package. It's documented in perlobj under the "Method Invocation" section.

Note, however, that SUPER bases itself on the current package, not the package of the instance you used it with.



回答3:

Method calls have a number of forms:

Calls method, possibly inherited:

->method()

Explicitly calls sub Package::method, whether that's in the inheritance tree or not:

->Package::method()

Explicitly calls the referred-to sub, whether that's in the inheritance tree or not:

->$coderef()

Calls the method that would have been called by __PACKAGE__->method() if there were no sub method in __PACKAGE__ (N.B. the class or object on the left of -> is irrelevant):

->SUPER::method()

Any of the above, depending on the contents of $method:

->$method()

(Legal even under use strict;.)

While the first form is the most common, it's worth learning about the others and how they work.



回答4:

To add to what derobert said:

You're calling 'new' in the 'SUPER' namespace but passing it the object (or string), '$class'.

You don't have to use SUPER, as you can give the full package name of the parent (useful in cases of diamond inheritance):

sub init {
   my $self = shift;
   $self->ParentClass1::init();
   $self->ParentClass2::init();
}


标签: perl oop