# Utility to run given Perl program line by line and print out # values as comments (for annotation) # Strictly brute-force. Watch out for side-effects! # # Vim users can use this like: # vmap !perl annotate.pl # nmap :.!perl annotate.pl use strict; package Annotate; # keep my own namespace so as not to pollute main use Data::Dumper(); $Data::Dumper::Indent = 0; $Data::Dumper::Terse = 1; $Data::Dumper::Useqq = 1; # these are locals so they're not visible in the evals. use vars qw(@program @sresults @aresults $programText $i $sresult @aresult); while (<>) { s/[\n\r\s]+$//; s/\s*##=> (?:array|scalar).*//; push ( @program, $_ ); } # set up Perl defaults: $programText = "no strict; package main;"; for $i ( 0 .. $#program ) { $programText .= $program[$i] . "\n"; $sresult = eval $programText; next if $@; @aresult = eval $programText; if ( @aresult == 1 && $aresult[0] == $sresult ) { $sresults[$i] = $sresult; } elsif ( scalar(@aresult) == $sresult ) { $aresults[$i] = [@aresult]; } else # different scalar and array results { $sresults[$i] = $sresult; $aresults[$i] = [@aresult]; } } die "error: $@" if $@; sub result { Data::Dumper->Dump( [shift] ) } for $i ( 0 .. $#program ) { print $program[$i]; if ( $program[$i] =~ /^[^#]*;(\s*#.*)?$/ && ( defined( $sresults[$i] ) || defined( $aresults[$i] ) ) ) { print "\t##=>"; print " scalar: ", result( $sresults[$i] ) if defined( $sresults[$i] ); print " array: ", result( $aresults[$i] ) if defined( $aresults[$i] ); } print "\n"; }