To see what is currently happening visit http://www.perl6.org/
Objects: use invocant pragma
Maintainer: Damian Conway <damian@conway.org> Date: 14 Sep 2000 Last Modified: 25 Sep 2000 Mailing List: perl6-language@perl.org Number: 223 Version: 2 Status: Frozen
This RFC proposes that, as in Perl 5, the invocant of a method should be
normally available to the method as $_[0], but that it can be
automaticaly stripped from @_ and accessed via either a subroutine
or a variable, using the use invocant pragma.
It is proposed that Perl 6 methods continue to receive their invocant (i.e. a reference to the object on which they were invoked) via $_[0].
This mechanism has served Perl 5 well and preserving it as the default will greatly simplify migration of OO Perl code.
It is, however, tedious that all Perl methods are thereby forced to start with:
sub method {
my ($self, @args) = @_;
...
}
or its various moral equivalents.
The problem may be eased somewhat in Perl 6, if methods can have proper parameter lists:
sub method ($self, @args) {
...
}
and this may, indeed, be sufficient.
However, it might also be useful if the invocant could be passed to a method via an entirely separate mechanism -- either a magic variable, or a magic subroutine.
The problem is: how to avoid the religious wars over which of these two alternative mechanisms is better, and what the chosen mechanism should be called.
It is therefore proposed that Perl 6 provide a pragma -- invocant -- that
takes the name of either a scalar variable or a subroutine and causes that
variable or subroutine to evaluate to the invocant of any method within
the lexical scope of the pragma. Furthermore, where the pragma is in effect,
methods would not receive their invocant as $_[0].
For example:
use invocant '$ME';
sub method {
$ME->{calls}++;
$ME->SUPER::method(@_);
}
or:
use invocant 'self';
sub method {
self->{calls}++;
self->SUPER::method(@_);
}
Note that there is no need to shift @_ before passing it to the ancestral
method, since the invocant is not prepended to the argument list in the first
place.
None. That's the point.
Pragma adds a trivial wrapper around affected methods. For example:
use invocant '$ME';
sub method {
$ME->{calls}++;
$ME->SUPER::method(@_);
}
becomes:
sub method {
my $ME = shift;
do {
$ME->{calls}++;
$ME->SUPER::method(@_);
}
}
whilst:
use invocant 'self';
sub method {
self->{calls}++;
self->SUPER::method(@_);
}
becomes:
sub method {
local *self = do { my $_invocant = shift; sub { $_invocant } };
do {
self->{calls}++;
self->SUPER::method(@_);
}
}
RFC 128 : Subroutines: Extend subroutine contexts to include name parameters and lazy arguments
RFC 137 : Overview: Perl OO should not be fundamentally changed.
RFC 152 : Replace invocant in @_ with self() builtin