File Coverage

blib/lib/B/OptreeShortestPath.pm
Criterion Covered Total %
statement 9 40 22.5
branch 0 24 0.0
condition 0 6 0.0
subroutine 3 8 37.5
pod 0 1 0.0
total 12 79 15.1


line stmt bran cond sub pod time code
1             package B::OptreeShortestPath;
2              
3 1     1   26888 use warnings;
  1         3  
  1         42  
4 1     1   7 use strict;
  1         3  
  1         42  
5 1     1   6 use B qw( svref_2object );
  1         3  
  1         1049  
6              
7             =head1 NAME
8              
9             B::OptreeShortestPath - The great new B::OptreeShortestPath!
10              
11             =head1 VERSION
12              
13             Version 0.02
14              
15             =cut
16              
17             our $VERSION = '0.02';
18              
19             =head1 DESCRIPTION
20              
21             This module adds the methods ->shortest_path( $op ) and ->all_paths()
22             to all B::OP objects in an optree.
23              
24             =head1 SYNOPSIS
25              
26             use B qw( main_root main_start );
27             use B::OptreeShortestPath;
28            
29             for ( main_start()->shortest_path( main_root() ) ) {
30             print "$_\n";
31             }
32              
33             =head1 METHODS
34              
35             =over 4
36              
37             =item $op->shortest_path( $other_op )
38              
39             Returns a list of the shortest paths from $op to $other_op. Each path
40             is a string approximating a bunch of chained method calls.
41              
42             "->next->sibling->next",
43             "->sibling->sibling->next"
44              
45             =cut
46              
47             sub B::OP::shortest_path {
48 0     0     my ( $op, $target ) = @_;
49 0           my $search = qr/\b$$op\b(.+)\b$$target\b/;
50              
51 0 0         return if $$op == $$target;
52              
53 0           my @paths;
54             my $len;
55 0           for ( $op->all_paths ) {
56 0 0         next unless /$search/;
57 0           $_ = $1;
58 0           tr/NOFS//cd;
59              
60 0 0         if ( not defined $len ) {
    0          
    0          
    0          
61 0           $len = length;
62 0           @paths = $_;
63             }
64             elsif ( $len < length ) {
65              
66             }
67             elsif ( $len == length ) {
68 0           my %seen;
69 0           @paths = grep !$seen{$_}++, @paths, $_;
70             }
71             elsif ( $len > length ) {
72 0           $len = length;
73 0           @paths = $_;
74             }
75              
76 0 0         die "@paths" if grep length() != $len, @paths;
77             }
78              
79             # Shortest paths, now fixing up for
80 0           for (@paths) {
81 0           s/N/->next/g;
82 0           s/F/->first/g;
83 0           s/O/->other/g;
84 0           s/S/->sibling/g;
85             }
86              
87 0           return @paths;
88             }
89              
90             =item $op->all_paths()
91              
92             Returns a list of paths from this node to all other nodes.
93              
94             =back
95              
96             =cut
97              
98             sub B::OP::all_paths {
99 0     0     my ( $op, $cx ) = @_;
100 0 0         $cx = '' if not defined $cx;
101 0 0         return "$cx SELF" if $cx =~ /\b$$op\b/;
102              
103             return (
104 0 0 0       ( $cx =~ /^(?:\d+ S )*(?:\d+ N )*$/
    0 0        
    0          
105             ? $op->next->all_paths("$cx$$op N ")
106             : ()
107             ),
108             ( $cx =~ /^(?:\d+ S )*(?:\d+ N )*(?:\d+ [FS] )*$/
109             && $op->can('first') ? $op->first->all_paths("$cx$$op F ")
110             : ()
111             ),
112             ( $cx =~ /^(?:\d+ S )*(?:\d+ N )*(?:\d+ [FS] )*$/
113             && $op->can('sibling') ? $op->sibling->all_paths("$cx$$op S ")
114             : ()
115             ),
116             );
117             }
118              
119 0     0     sub B::NULL::all_paths {"$_[1]NULL"}
120              
121             sub compile {
122             return sub {
123 0     0     my $sub = svref_2object( sub { 1 for 1; } );
  0            
124 0           print "$_\n" for $sub->START->shortest_path( $sub->ROOT );
125              
126 0     0 0   };
127             }
128              
129             =head1 AUTHOR
130              
131             Joshua ben Jore, C<< >>
132              
133             =head1 BUGS
134              
135             Please report any bugs or feature requests to
136             C, or through the web interface at
137             L.
138             I will be notified, and then you'll automatically be notified of progress on
139             your bug as I make changes.
140              
141             =head1 ACKNOWLEDGEMENTS
142              
143             =head1 COPYRIGHT & LICENSE
144              
145             Copyright 2005 Joshua ben Jore, all rights reserved.
146              
147             This program is free software; you can redistribute it and/or modify it
148             under the same terms as Perl itself.
149              
150             =cut
151              
152             qq[ "Hey, what does this switch labeled 'Pulsating Ejector' do?"
153             "I don't know... I've always been too afraid to find out" ];