The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Devel::Graph - Turn Perl code into a graphical flowchart

SYNOPSIS

        use Devel::Graph;
        my $grapher = Devel::Graph->new();

        my $graph = $grapher->decompose( \'if ($b == 1) { $a = 9; }' );
        print $graph->as_ascii();

        # Will result in something like this:

        ################
        #    start     #
        ################
          |
          |
          v
        +--------------+
        | if ($b == 1) |--+
        +--------------+  |
          |               |
          | true          |
          v               |
        +--------------+  |
        |   $a = 9;    |  | false
        +--------------+  |
          |               |
          |               |
          v               |
        ################  |
        #     end      # <+
        ################

        # Alternatively, read in code from a file
        my $graph_2 = $grapher->decompose( 'lib/Foo.pm' );
        print $graph_2->as_ascii();

DESCRIPTION

This module decomposes Perl code into blocks and generates a Graph::Flowchart object out of these. The resulting object represents the code in a flowchart manner and it can return an Graph::Easy object.

This in turn can be converted it into all output formats currently supported by Graph::Easy, namely HTML, SVG, ASCII art, Unicode art, graphviz code (which then can be rendered as PNG etc) etc.

Parsing

The parsing is done by PPI, so everything that is supported properly by PPI should work.

Customizing the flowchart

Per default, the flowchart will have certain properties, like bold start/end blocks, diamond-shaped if-blocks and so on. You can change these by setting class attributes on the returned graph object:

        use Devel::Graph;
        my $g = Devel::Graph->graph( '$a = 9 if $b == 1' );

        $g->set_attribute('node.if', 'fill', 'red');    # if blocks: red
        $g->set_attribute('node.for', 'fill', 'blue');  # for blocks: blue
        $g->set_attribute('edge.true', 'style', 'bold');# true edges: bold
        print $g->as_html_file();

Subclasses for node include if, for, start, end, continue etc. For a list of all possible classes see Graph::Flowchart, and for a list of all possible attributes and their values, see Graph::Easy.

EXPORT

Exports nothing.

METHODS

graph() provides a simple function-style interface, while all other methods are for an object-oriented model.

graph()

        my $graph = Devel::Graph->graph( \$code );
        my $graph = Devel::Graph->graph( $filename );

Takes Perl code in $code (as SCALAR ref or scalar filename) and returns a flowchart as Graph::Easy object. It will strip all POD before composing the flowchart.

This is a shortcut to avoid the OO interface described below, you should better use this:

        my $code = \'$a = 9;';
        my $flow = Devel::Graph->new();
        $flow->decompose( $code );
        $flow->finish();
        my $graph = $grapher->as_graph();

Please see Graph::Easy for further details on what to do with the returned object.

new()

        my $flow = Devel::Graph->new( $options );
        my $flow_2 = Devel::Graph->new( { strip_pod => 0 } );

Creates a new Devel::Graph object.

The optional $options is a hash reference with parameters. The following arguments are valid:

        strip_pod       Strip all POD before doing the graph. Defaults to true.
                        POD sections are usually very large, resulting in huge
                        nodes, that can, f.i. crash graphviz or result in
                        poor output quality.
        debug           Defaults to false. When set to true, enables debug output.
        fatal_errors    Defaults to true. When set to true, errors are fatal.

option()

        my $option = $flow->option($name);

Return the option with the given name from the Devel::Graph object.

debug()

        my $debug = $grapher->debug();  # get
        $grapher->debug(1);             # enable
        $grapher->debug(0);             # disable

Enable, disable or read out the debug status. When the debug status is true, additional debug messages will be printed on STDERR.

decompose()

        $flow->decompose( \$code );             # \'$a = 1;'
        $flow->decompose( $filename );          # 'lib/Package.pm'

Takes Perl code (scalar ref in $code) or Perl file (filename in $code) and decomposes it into blocks and updates the internal structures with a flowchart representing this code.

If called more than one time, the code will be added to the flowchart. To get a new, empty flowchart, use reset().

finish()

        $flow->finish();

Finish the flowchart by attaching an end node to the current node.

reset()

        $flow->reset();

Reset the internal state of the object, so that decompose() will create a new flowchart.

as_graph()

        my $graph = $flow->as_graph();

Return the internal data structure as Graph::Easy object.

as_ascii()

        print $flow->as_ascii();

Return the flow chart as ASCII art. Shortcut for $grapher-as_graph->as_ascii()>.

as_flowchart()

        my $chart = $flow->as_flowchart();

Return the internal data structure as Graph::Flowchart object.

BUGS

Not all Perl constructs are implemented yet, especially the more esoteric Perl constructs.

Also, things like <$a = 9 if $b == 9> (no () around the condition) are buggy and/or incomplete, due to the way PPI parses the code.

Help in testing and bugreports are always welcome!

SEE ALSO

Graph::Easy, Graph::Flowchart, PPI, B::Graph.

COPYRIGHT AND LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms of the GPL version 2. See the LICENSE file for information.

AUTHOR

Copyright (C) 2004-2007 by Tels http://bloodgate.com