RFC 187 (v1) Objects : Mandatory and enhanced second argument to C<bless>

[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

Objects : Mandatory and enhanced second argument to C<bless>

=head1 VERSION

  Maintainer: Damian Conway <[email protected]>
  Date: 1 September 2000
  Mailing List: [email protected]
  Version: 1
  Number: 187
  Status: Developing

=head1 ABSTRACT

This RFC proposes that the second argument to C<bless> be made
mandatory, and that its semantics be enhanced slightly to cover a
common, ugly, and frequently buggy usage.

=head1 DESCRIPTION

=head2 Mandatory second argument

When omitted, the second argument to C<bless> currently defaults to the
name of the package from which the call is made. This default behaviour
leads to unexpected and undesirable behaviour whenever a constructor
is inherited by a derived class:

        package Base;
        
        sub new { bless {} }
        
        
        package Derived;
        use base 'Base';
        
        
        package main;
        
        $obj = Derived->new();          # Creates an object blessed into Base!
        

To remove this nasty surprise is proposed that the second argument to
C<bless> be made mandatory.


=head2 Extended second argument semantics

A common idiom in OO Perl is to allow constructors to be called
as both class- and object- methods by writing:

        sub new {
                bless {}, ref($_[0]) || $_[0];
        }
        
It is proposed that the above clutter be rendered unnecessary.
Specifically, if the second argument to C<bless> is a reference,
that it be stringified by calling C<ref>, rather than by the usual
stringification process.

This would allow the above example to be written as:

        sub new {
                bless {}, $_[0];
        }
        
More importantly, it would allow calls to C<bless> which I<don't>
use the C<ref($_[0])||$_[0]> idiom to Do The Right Thing,
instead of the existing bizarre behaviour (i.e. blessing 
into classes with names like C<'MyClass=HASH(0x5a7f590)'> [sic].


=head2 Alternative (restricted) second argument semantics

An alternative to extending the semantics of the second argument, would
be to cause C<bless> to issue a warning or exception when called with a
reference as its second argument. This would still require an explicit
C<ref($_[0])||$_[0]> where such behaviour was desired, but would catch
erroneous uses.

And anyone truly desiring the bizarre existing behaviour could
simply use:

        sub new {
                bless {}, "$_[0]";
        }
        
=head1 MIGRATION

Minimal, since only the truly wicked ever invoke C<bless> with only
one argument.

Migration would consist of translating instances of:

        bless REF;
        
to:
        
        bless REF, __PACKAGE__;         # Note: this may break inheritance!
        
        
Changes to second argument semantics would have no impact except in
pathological cases. In practice, the new semantics would silently fix a
large number of lurking bugs in existing code.


=head1 IMPLEMENTATION

Trivial.

=head1 REFERENCES

I<perltoot>

Conway, I<Object Oriented Perl>, p. 77 & 172
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.