method call works with non-existent invocant

U

Unknown Poster

I don't see how this not only compiles under Perl 5.6.1, but the call to
init() in the Parent class works, with a scalar or bareword that refers
to nothing. (It fails if there is no invocant at all.) Why is the call
seen below considered OK by the compiler?

-------------------

package Child;

use base("Parent");
use strict;
use warnings;

sub new
{
my $i = shift;
my $hr = x->SUPER::init(); #or even $x
my $s = {%$hr, count => 0, label => 'none'};
return bless $s, ref($i) || $i;
}

..
..
..
 
T

Tassilo v. Parseval

Also sprach Unknown Poster:
I don't see how this not only compiles under Perl 5.6.1, but the call to
init() in the Parent class works, with a scalar or bareword that refers
to nothing. (It fails if there is no invocant at all.) Why is the call
seen below considered OK by the compiler?

-------------------

package Child;

use base("Parent");
use strict;
use warnings;

sub new
{
my $i = shift;
my $hr = x->SUPER::init(); #or even $x
my $s = {%$hr, count => 0, label => 'none'};
return bless $s, ref($i) || $i;
}

First of all, this is not so much an issue of the compiler. Perl's
compiler just creates an op-tree which wont fail as long as your script
is syntactically correct. If the above was an error, it would be
detected by the interpreter at runtime.

However, the above is totally ok. Using SUPER:: will change Perl's
notion of method dispatch. Which class' method is invoked now no longer
depends on the invocant but rather on the first value in @Child::ISA:

package A;
sub init { print "@_\n" }
package B;
@B::ISA = qw/A/;
x->SUPER::init(1, 2, 3);
__END__
x 1 2 3

This makes sense as you explicitely asked to call the init() method of
the superclass. In this case perl wont look at the invocant at all.
Instead it will eventually translate the above to:

A::init("x", 1, 2, 3);

The following example shows more clearly that perl ignores the type of
invocant when SUPER:: was given:

package A;
sub init { print "A::init: @_\n" }

package B;
@B::ISA = qw/A/;
sub init { print "B::init: @_\n" }

$x = bless { } => __PACKAGE__;
$x->init(1, 2, 3);
$x->SUPER::init(1, 2, 3);
__END__
B::init: B=HASH(0x8139c84) 1 2 3
A::init: B=HASH(0x8139c84) 1 2 3

Tassilo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top