develooper Front page | perl.perl5.porters | Postings from May 2008

thoughts about overloading method calls

Thread Next
From:
Ricardo SIGNES
Date:
May 6, 2008 08:37
Subject:
thoughts about overloading method calls
Message ID:
20080506153649.GA649@68-29-114-151.area4.spcsdns.net

Today, I was doing some mucking about with class data, generated packages, and
Class::ISA, and I started to wail and gnash my teeth.  I cried, "Why can't I
just replaced the darn object system?"

It would let me use any kind of MRO I wanted, including some crazy MRO that I
only want in one extreme case.  It would let me do truly classless OO, avoiding
the pseudo-anonymous "classes" created by things like Package::Generator.  It
would let me have a clear distinction between class and object methods.

A truly anemic start would be to write classes with no methods save for
AUTOLOAD.  Unfortunately, AUTOLOAD does not catch universal methods.  This is
worse than just having to write a "can" and "isa."  If anything in your process
loads UNIVERSAL::{moniker,require} or Sub::Install, or any of a number of other
things that muck with UNIVERSAL, your code will change in bizarre ways.

What if, instead, I could overload method calls on an object?

  package Classless::Root;
  use overload method => 'invoke_method';

  sub new {
    my ($class, %attr) = @_;
    
    my $root = { ... universal prototype ... };

    my $obj = { parent => $root, attr => \%attr };
    return bless $obj => $class;
  }

  sub invoke_method {
    my ($self, $name, $arg_ref) = @_;

    my $iter = (ref $self)->parent_climber($self);
    while (my $obj = $iter->next) {
      next unless exists $obj->{attr}{$name};
      $obj->{attr}{$name}->(@$arg_ref);
    }
  }

Other class construction kits could use this to produce class objects.

  my $class = Class::Metameta->new({ ...class definition... });
  my $instance = $class->new({ ...instance data... });

These might both be objects blessed into Class::Metameta.  The bless target
(the result of "ref") would now refer not specifically to the object's class in
the traditional sense, but to the package in which the object's behavior would
be defined -- either as a "traditional" Perl class or as a method dispatching
system.

I imagine this would confuse calling (UNIVERSAL::isa(x)), but it's hard to
care.  It would also mean that UNIVERSAL would only be the default for
"default" classes.  I think that's a benefit, rather than a problem.  I have a
nagging suspicion that making this work with indirect method calls would be
obnoxious.  Again, I have a hard time seeing that as a problem.  It could be
documented.

So, what I'm wondering is:

  a) am I totally wrong and stupid?  please point out how and why

  b) how difficult would this be to accomplish?

-- 
rjbs

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About