package GraphViz::ISA::Multi; use strict; use GraphViz; use Carp; BEGIN { use Exporter (); use vars qw ($VERSION @ISA); $VERSION = 0.02; } sub new { my ($class, %parameters) = @_; my $self = bless ({}, ref ($class) || $class); $self->{data} = {}; $self->{ignore} = $parameters{ignore}; $self->{changed} = 0; return ($self); } sub graph { my $self = shift; return $self->{g} unless $self->{changed}; $self->{g} = GraphViz->new(); ### draw all nodes: foreach my $module (sort keys %{$self->{data}}) { $self->{g}->add_node($module); foreach my $nod (@{$self->{data}->{$module}}) { $self->{g}->add_node($nod) ; } } ### draw the edges foreach my $module (sort keys %{$self->{data}}) { $self->{g}->add_edge($_, $module) for @{$self->{data}->{$module}}; } $self->{changed} = 0; return $self->{g}; } sub add { my $self = shift; my @to_add = @_; foreach my $module (@to_add) { next if grep /$module/i, @{$self->{ignore}}; next if $self->{data}->{$module}; my $filename = $module; $filename =~ s!::!/!g; $filename .= ".pm"; my @pkg = ($module); eval { require $filename; # if we got more packages in a file, find them open my $fg, "<$INC{$filename}" or croak "$!\n"; foreach my $line (<$fg>) { if ($line =~ /package (.+);/) { push @pkg, $1 unless $1 eq $module; } } close $fg; }; if ($@) { return undef; } no strict 'refs'; foreach my $mod (@pkg) { if (@{$mod . "::ISA"} > 0) { $self->{data}->{$mod} = \@{$mod."::ISA"}; foreach my $ign (@{$self->{ignore}}) { @{$self->{data}->{$mod}} = grep $_ !~ /$ign/, @{$self->{data}->{$mod}}; } $self->add($_) foreach @{$mod."::ISA"}; } } } $self->{changed} = 1; return $self->{data}; } sub AUTOLOAD { no strict 'vars'; my $self = shift; my $n = $AUTOLOAD; $n =~ s/.*:://g; return if $n =~ /DESTROY/; if ($n =~ /as_/) { $self->graph(); } ### give it down to GraphViz: $self->{g}->$n(@_); } 1; #this line is important and will help the module return a true value __END__ =head1 NAME GraphViz::ISA::Multi - Display ISA relations between modules =head1 SYNOPSIS use GraphViz::ISA::Multi; my $gnew= GraphViz::ISA::Multi->new(ignore => [ 'Exporter' ]); $gnew->add("Curses::UI::TextViewer" ); $gnew->add("Curses::UI::Listbox" ); print $gnew->as_png(); =head1 DESCRIPTION GraphViz::ISA::Multi visualizes the ISA relations between multiple modules. It is a addition to GraphViz::ISA, which can only show the ISA tree of one module. =head1 USAGE =over 4 =item new( ignore => ARRAYREF ) Creates a new GraphViz::ISA::Multi object. Takes as an additional parameter the 'ignore' => [ 'Module' ] list, which tells the object to not display certain modules in the graphic. =item add( MODULENAMELIST ) Adds packages to the graphic. Takes a list of module names and returns the data structure used to display the graphic on success. On error it returns a false value (undef). =item graph( ) Used to create the actual GraphViz object and graphic. You usually don't call this directly as it is called when you call one of the as_* methods. You can override if it you subclass the class. It returns the GraphViz object on success. =item as_png( ) See GraphViz() for more details. =back =head1 AUTHOR Marcus Thiesen marcus@cpan.org http://perl.thiesenweb.de =head1 COPYRIGHT This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of the license can be found in the LICENSE file included with this module. =head1 SEE ALSO perl(1). =cut