RFC 152 (v1) Replace $self in @_ with self() builtin (not $ME)

[email protected] (Perl6 RFC Librarian)
Newsgroups perl.perl6.language.objects,perl.perl6.announce
Message-ID <[email protected]>
This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Replace $self in @_ with self() builtin (not $ME)

=head1 VERSION

   Maintainer: Nathan Wiger <[email protected]>
   Date: 24 Aug 2000
   Version: 1
   Mailing List: [email protected]
   Number: 152
   Status: Developing

=head1 ABSTRACT

Currently, the current object context is passed into a sub as the first
element of @_, leading to the familiar construct:

   my $self = shift;

However, this is a big PITA. In particular, if you support lots of
different calling forms (like CGI.pm), you have to check whether $_[0]
is a ref, etc, etc, etc.

Much discussion has begun about the proposed $ME variable, which could
automatically contain this information. However, getting its scoping and
value right is a mess, and will result in a horrendous $AUTOLOAD
disaster that should not be repeated.

This RFC, therefore, proposes a new builtin called C<self()> which will
return the correct package information. This has the added advantage
that it is consistent with C<ref()>, C<want()>, and other context
functions.

=head1 DESCRIPTION

The new function C<self()> would be called in the following way:

   sub do_stuff {
       my $self = self;
       $self->{STATE}->{something} = @_;
   }

   sub error {
       carp @_ if self->config('VerboseErrors');
   }

The return value of C<self()> would similar to the current value in
$_[0], with increased flexibility. In particular, it can be called
anywhere and everywhere, not just within a sub.

Depending on the context it's called in, the return value of C<self()>
will be:

   1. A reference to the object, within an object

   2. The name of the package, within a package

   3. A reference to the sub itself, within a non-method

These different return values give us the ability to call C<self()>
anywhere within Perl 6 code:

   package MyPackage;
   # ... many other functions ...
   sub do_stuff {
       print "Hello, @_" if self->config('Yep');
   }
   self->do_stuff;        # MyPackage->do_stuff

   package main;
   my $mp = new MyPackage;
   $mp->config('Yep') = 1;
   $mp->do_stuff('Nate'); # prints "Hello, Nate"

In addition, having a routine called C<self()> has the major advantage
that it hides the internal magic and scoping from the user. Just like
using C<want()> instead of a special variable called C<$WANT>, C<self()>
makes using and comprehending contexts easy ("just call 'self'").

Finally, it may be possible for self() to take an additional argument.
For example:

   # Only return $self if are in the context of the class
   # that is named 'DefaultClass' (see CGI.pm for an ex.)
   if (my $self = self('DefaultClass')) {
      $self->do_stuff;
   } else {
      # do something else
   }

This is not required by the RFC, but seems like a useful extension.

=head1 IMPLEMENTATION

Replace the ref usually included in $_[0] with C<self()>. Stop passing
$self in @_.

=head1 MIGRATION

p52p6 would have to catch

   my $self = shift;

and all other similar constructs and change them to

   my $self = self;

or the equivalent.

=head1 REFERENCES

Mail archives on the $ME discussion:
http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00023.html
http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00025.html
http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00026.html 

RFC 21: Replace C<wantarray> with a generic C<want> function
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.