################################## # complain.pl - find what's wrong with others' code fast! # input should come from STDIN. # options: --plugin - use the named plugin # --verbose - display some stuff use strict; use warings; use Linux; use Mozilla; # OK, ommit this one :-) # General tool stuff use Getopt::Long; my @plugins; my $verbose; GetOptions('plugin=s' => \@plugins, 'verbose' => \$verbose); # Get input program. my $snippet = eval {local $/; return < >}; print $snippet if $verbose; #### foreach (@plugin_list) { require $_ or warn "Plugin $_ failed to load"; } #### # Load plugins @plugins = grep { eval{require "plugins/$_.pl"} ? 1 : (warn("Plug-in $_ failed to load.\n"), 0) } @plugins; #### require Acme::Current; # or use Acme::Current; #### use Module LIST; require EXPR; #### foreach (@plugin_list) { $_->init; } #### # Do the stuff foreach (@plugins) { $_->evaluate($snippet); } #### # Initialization: foreach (@plugins) { $_->init if UNIVERSAL::can($_, 'init'); } #### ############################# # plugins/bench.pl package bench; use Benchmark; sub evaluate { my $pkg = shift; my $snippet = shift; print timestr(timeit(400000, $snippet)), "\n"; } 1; #### $ ./complain.pl -p bench < snippet.txt #### package Context; my %versions = (); # The returned hash will store for each plugin the complaints it registers. sub new { my $class = shift; return bless {}, $class; } # This will be optional. sub declareVersion { my $self = shift; my ($plugin, $version) = @_; $versions{$plugin} = $version; } # That's for our program sub getVersion { shift; $versions{shift()} } # This is how the plugin will tell us what he thinks, as many # times as it wants to. sub addOpinion { my $self = shift; my ($plugin, $opinion) = @_; $self->{$plugin} = [] unless exists $self->{$plugin}; push @{$self->{$plugin}}, $opinion; } #### # Start a new context; my $ctx = Context->new; # Initialization: foreach (@plugins) { $_->init($ctx) if UNIVERSAL::can($_, 'init'); } # Do the stuff foreach (@plugins) { $_->evaluate($ctx, $snippet); } #### sub evaluate { my $pkg = shift; my ($ctx, $snippet) = @_; $ctx->addOpinion($pkg, timestr(timeit(400000, $snippet))); } #### # Simple output. while (my ($plugin, $opinions) = each %$ctx) { my $ver = undef; my $verstr = ($ver = Context->getVersion($plugin)) ? "(Version $ver) " : ''; print "The plugin $plugin ${verstr}says:\n"; print join '\n', map { "\t$_\n" } @$opinions; } #### ############################### # plugins/grammar.pl package grammar; sub init { my $pkg = shift; my $ctx = shift; $ctx->declareVersion($pkg, '0.1'); } sub evaluate { my $pkg = shift; my ($ctx, $snippet) = @_; if ($snippet =~ /use\s+strict;/) { $ctx->addOpinion($pkg, "Uses strict. OK"); } else { $ctx->addOpinion($pkg, "Does not use strict; Heathen swine!!"); } } 1; #### perl -e'$b=unpack"b*",pack"H*","59dfce2d6b1664d3b26cd9969503";\ for(;$a