On 8/17/00 5:36 PM, Perl6 RFC Librarian wrote:
> NOTE: these and other examples assume Highlander Variables (RFC 9)
> where '$mage', '@mage' and '%mage' all refer to different "views" of
> the same variable, rather than different variables as in Perl 5.
> Otherwise read '@mage' as '@$mage' and '%mage' as '%$mage'.

I don't agree with the premise that objects should look and behave like
traditional Perl data structures.  Objects are objects, not arrays or
hashes.  The farthest I'd go is using scalars to hold references to objects.

    $mage = Person->new(...);

Object attributes should be accessed through accessors that look and behave
like accessors:

    $name = $mage->name;

The default behavior for attributes should be get/set, not just get.  I
never, ever want to have to write a method like this:

> sub name {                # specific accessor method
>   if (@_) {
>   $name = shift;
>    print "changed name to $name\n"
>      if $debug;
>   }
>   return $name;
> }

Get/set should be the default, stupendously efficient behavior:

    $mage->name('Merlin'); # Be fast!

    print $mage->name; # Be fast!

An attribute should be able to hold any valid Perl value:

    $mage->friends([ 'Gandalf', 'Oz' ]);
    $mage->warts({ big => 5, small => 2 });

possibly including collections:

    $mage->spells('fire', 'wind', 'ice');

    print 'Summon the ', ($mage->spells)[1];

    $mage->robes(big => 7, small => 2);

Again, this is the default, no-need-to-roll-your-own, wickedly fast native
object attribute access interface.

As for interpolation into strings:

    print "$mage->name commands you!";

I can take it or leave it.  It seems like it might muck things unless you
also allow user-defined methods to interpolate as well.
   
This type of attribute assignment:

> $Person->debug = 1;            # activate debugging

also alienates user-defined methods unless you're willing to go puck
nutty with lvalue subs (which give me the willies).

> # EITHER
> my $mage = Person->new(  # use positional parameters
> "Gandalf", 
> "Istar", 
> ["Mithrandir", "Olorin", "Incanus"]
> );

Positional parameter construction support is fine, but this is better:

> # OR
> my $mage = Person->new(  # use named parameters
> name    => "Gandalf",
> race    => "Istar",
> aliases => ["Mithrandir", "Olorin", "Incanus"]
> );

Like I said, I think this is evil:

> print " aka: @mage->aliases\n"; # ditto

If "aliases" contains an array:

    $mage->aliases('Fred', 'Joe');

then it should work like this:

    print $mage->aliases;   # "FredJoe"

    # If you allow interpolation:
    print "$mage->aliases;" # "Fred Joe"

More evil:

> # use it like a list
> my ($name, $race, $aliases) = @mage;

Ick, please no.  First of all, if you want an array, use an array. Second, I
never want to have to know the order of an object's attributes!  Talk about
fragile.
 
> # use it like a hash, with keys returned in correct order
> my @keys = keys %mage;        # 'name', 'race', 'aliases'

Ditto.  Bleh.

I'd like to see a *distinct syntax and implementation* for objects. (The
following example is just off the top of my head and is not meant to be a
syntax recommendation, but the spirit is there.)

Classes should be called classes, not packages.  We could even keep packages
and the whole Perl 5 o-o implementation around.  It won't interfere with
Perl 6 o-o because Perl 6 o-o does not dress up and overload normal data
structures to make "objects."  So yes, it should be:

    class Person;

Same deal with methods.  Subroutines are subroutines and methods are
methods.  Let's say we want to do more than set/get the name attribute via a
single scalar:

    method name
    {
      my($first, $last) = @_;

      $self.name = $first . ' ' . $last;
    }

Here we see an implicit $self (available in all methods), normal arg
handling via @_ (with the 0th arg no longer being a ref to self), a new
syntax for accessing attributes inside custom methods of the same name
($self.name), and an implicit return of the name attribute (did I mention
that get/set should return the current/new value of an attribute?)

All of the syntax and rules in this example are arbitrary, however.  The
take-home point here is that *this is a METHOD*, not a fancy subroutine.

The same goes for classes themselves, which should be "class objects" that
instantiate objects by cloning a prototype or what have you, so we can stop
slinging around "Strings::Like::This"

Summary: Perl 6's o-o syntax and implementation should not be constrained by
Perl 6's procedural interface, nor should it be shoehorned into overloaded
versions of Perl data structures.

-John

Reply via email to