This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects: C<use invocant> pragma

=head1 VERSION

  Maintainer: Damian Conway <[EMAIL PROTECTED]>
  Date: 14 Sep 2000
  Last Modified: 25 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 223
  Version: 2
  Status: Frozen

=head1 ABSTRACT

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 C<use invocant> pragma.


=head1 DESCRIPTION

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 -- C<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 I<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 C<shift> @_ before passing it to the ancestral
method, since the invocant is not prepended to the argument list in the first
place.


=head1 MIGRATION ISSUES

None. That's the point.


=head1 IMPLEMENTATION

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(@_);
            }
        }


=head1 REFERENCES

RFC 128 : Subroutines: Extend subroutine contexts to include name parameters and lazy 
arguments 

RFC 137 : Overview: Perl OO should I<not> be fundamentally changed.

RFC 152 : Replace invocant in @_ with self() builtin

Reply via email to