Class::C3 Wierdness?

Ovid on 2009-01-31T16:22:19

Playing around with different MROs to try and figure out general purpose algorithms for detecting 'unreachable' methods. That's when I got confused by Class::C3. Imagine the following hierarchy. If every one of those classes has a 'target' method, I expect, with C3, that the calling order would be "One", "Two", "Three", "Four", "Six" and "Five".

     5
     |
     4  6
     | /
  2  3
   \ |
     1

Here's my code:

#!/usr/bin/perl -l

use strict;
use warnings;

package One;
our @ISA = qw/Two Three/;
use Class::C3;
sub target { print __PACKAGE__; shift->next::method }

package Two;
use Class::C3;
sub target { print __PACKAGE__; shift->next::method }

package Three;
our @ISA = qw/Four Six/;
use Class::C3;
sub target { print __PACKAGE__; shift->next::method }

package Four;
our @ISA = 'Five';
use Class::C3;
sub target { print __PACKAGE__; shift->next::method }

package Five;
use Class::C3;
sub target { print __PACKAGE__; shift->next::method }

package Six;
use Class::C3;
sub target { print __PACKAGE__; shift->next::method }

package main;
Class::C3::initialize();
One->target;

This prints out:

One
Two
Three
Four
Five
Six

Because 'Three' inherits from 'Four' and 'Six', I'm expecting 'Six' to get called before 'Five' (which 'Four' inherits from). What did I miss?

Note: the rationale behind this was simple. Let's say that only 'Two' and 'Six' define a 'target' method (the graphic I created to understand this). With Perl's default MRO, '&Six::target' is unreachable. I wasn't sure if that was the case with Class::C3. That's why I'm a bit confused.


Correct behavior

melo on 2009-01-31T17:41:03

Hi,

According to Class::C3 docs, the C3 algorithm only guarantees that no class Parent will be called before Child.

In your case, when he gets to '4', he can call '5' because '6' is not a subclass of '5'.

If you add Five to the @Six::ISA, then you would see the behavior that you are expecting.

Best regards,

Re:Correct behavior

Ovid on 2009-01-31T18:49:18

Ah, OK. Thanks!