Before and After Graphs (Role Application)

Ovid on 2009-04-09T14:24:17

I've finished the first pass at reorganizing some of our code with roles. Take a look at our inheritance hierarchy before we switched to roles.

Now look at it after we switched to roles.

Nice and flat, eh? Which would you rather work on?

Of course, it's been pointed out (an annoyingly fair critique, I might add), that the latter graph doesn't show as much information. So here's the same graph with every class showing which roles it uses.

We have 10 roles. None of them are very large and most have fairly descriptive names. Learn those 10 roles and you can instantly get an idea of what each and every class does.

To generate the latter graph, I used a modification of kzys's code to list methods for each class.

#!/usr/bin/env perl

use strict;
use warnings;
use Class::Sniff;

sub package_of {
    my ($path) = @_;

    if ($path !~ m|/?lib/(.*)\.pm$|) {
        die;
    }

    my $result = $1;
    $result =~ s|/|::|g;
    return $result;
}

sub new_roles {
    my ($sniffer) = @_;

    my $klass = $sniffer->target_class;
    my @roles = $klass->meta->calculate_all_roles;
    shift @roles;
    @roles = map { $_->identifier } @roles;
    @roles = 'No roles implemented' unless @roles;
    return @roles;
}

my @sniffs = map {
    my $package = package_of($_);
    eval "use $package";

    Class::Sniff->new({
        class  => $package,
        ignore => qr/^(::DBIx|Class)/,
    });
} @ARGV;

my $labels = join "\n", map {
    my @roles = new_roles($_);

    my $label = '{\N\n|' . join('\l', sort @roles) . '\l}';
    $label =~ s/"/\\"/g;

    sprintf('"%s" [label="%s"]', $_->target_class, $label);
} @sniffs;

my $sniff    = pop @sniffs;
my $graphviz = $sniff->combine_graphs(@sniffs)->as_graphviz;

# it's dirty...
$graphviz =~ s/}/$labels }/g;
$graphviz =~ s/shape=box/shape=record/g;

print $graphviz;

And you can run it with this:

find lib/PIPs/ResultSet/ -name '*pm'|egrep -v 'Role' |xargs perl role_sniff.pl > role_sniff.viz


sold

markjugg on 2009-04-10T15:06:01

Ovid,

I regularly read and enjoy your blog posts. I think your latest series on roles has sold me on moving more in that direction in my own work.

I agree it seems like a cleaner, clearer organizational model than focusing on inheritance.

Cool stuff

grink on 2009-04-10T21:03:34

Very cool post, thanks