This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Replace invocant in @_ with self() builtin =head1 VERSION Maintainer: Nathan Wiger <[EMAIL PROTECTED]> Date: 24 Aug 2000 Last Modified: 24 Sep 2000 Mailing List: [EMAIL PROTECTED] Number: 152 Version: 2 Status: Frozen =head1 ABSTRACT Currently, the invocant 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 several different calling forms (like CGI.pm), you have to check whether $_[0] is a ref or class name, etc. This RFC, therefore, proposes a new builtin called C<self()> which will return the correct invocant information. This has the added advantage that it is consistent with C<caller()>, C<want()>, <ref()>, and other context functions. =head1 DESCRIPTION =head2 Syntax The new function C<self()> would be called in the following way: sub fullname { my $self = self; @_ ? $self->{STATE}->{fullname} = $_[0] : $self->{STATE}->{fullname}; } sub my_junk { my $this = self; $this->fork_o_matic(@_); } # Or even... sub error { carp @_ if self->config('VerboseErrors'); } sub uid { @_ ? self->{uid} = $_[0] : self->{uid}; } The return value of C<self()> would be similar to the current invocant in $_[0], with increased flexibility. In particular, it can be called anywhere and everywhere, not just within a method. 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 method 2. The name of the package, within a package 3. Undef, if a sub is not called as a 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, simply changing the Perl 5 rule: "The invocant is passed into subs as $_[0] in OO contexts" To the simpler still: "The invocant is always gotten by calling self()" This provides a consistent interface, since C<self()> can be called anywhere, just like C<caller()>, C<want()>, and other context functions. =head2 Arguments against C<use invocant> This RFC was released prior to, and remains in opposition to, RFC 233, which proposes a C<use invocant> pragma that provides the flexibility to name the invocant anything you want. As many have noted, Perl is already hard enough. C<use invocant> only gives us multiple ways to do something without adding value, only confusion, by promoting an inconsistent interface. Like providing a means to rename C<@ARGV> and C<STDIN> because a person prefers C<@args> and C<output>, C<use invocant> further complicates an issue which should only be made easier. The author of this RFC B<loves> Perl and loves its flexibility. However, just like choosing a name for C<caller>, C<want>, C<print>, C<@ARGV>, and so forth, we need to choose a name for C<self> as well to ease the burden on the programmer. "Choosing an interface" does not amount to "being un-Perlish" as some might purport to suggest. In fact, just the opposite: We're decreasing the amount of time a user has to spend decoding somebody else's invocant naming scheme by providing a very Perlishly-named function. B<This makes things easier>. If it is vital that the invocant must be named something specific, then a person can always use a sub wrapper, tie, or a typeglob to rename it appropriately. Actually, they don't even have to go to these extremes since they can still do this: sub getdata { my $this = self; return $this->{DATA}->{$_[0]}; } (that is, assign to a custom variable) anywhere they want to. Finally, the author would be more than happy to settle for the selection of something different than C<self>, such as C<this()>, C<$SELF>, or even C<$ME>. The main point is that we need to choose something, because doing so makes the language more consistent and easier (combatting two widespread criticisms of Perl). =head1 IMPLEMENTATION Replace the invocant usually included in $_[0] with C<self()>. Stop passing the invocant in @_. =head1 MIGRATION Backwards compatibility is simple. Subs can simply have the expression: unshift @_, self if self; Added as the first line of the sub, since C<self()> will return undef if not in an OO context. =head1 REFERENCES Critique of the C<use invocant> pragma: http://www.mail-archive.com/perl6-language@perl.org/msg03952.html Outline of the benefits of C<self>: http://www.mail-archive.com/perl6-language-objects@perl.org/msg00074.html RFC 21: Replace C<wantarray> with a generic C<want> function RFC 233: Objects: C<use invocant> pragma