- pre processor - processor - post processor - engine #### sub engines { trace() if $ENV{TRACE}; my $self = shift; my $module = $self->{namespace} . "::Engine"; my $engine = $module->new; my @engines; for (keys %{$engine->_dt}){ push @engines, $_ if $_ !~ /^_/; } return @engines; } #### sub new { trace() if $ENV{TRACE}; my $self = {}; bless $self, shift; $self->{engines} = $self->_dt; return $self; } sub _dt { trace() if $ENV{TRACE}; my $self = shift; my $dt = { all => \&all, has => \&has, missing => \&missing, lines => \&lines, objects => \&objects, search_replace => \&search_replace, inject_after => \&inject_after, dt_test => \&dt_test, _test => \&_test, _test_bad => \&_test_bad, }; return $dt; } #### sub all { trace() if $ENV{TRACE}; return sub { trace() if $ENV{TRACE}; my $p = shift; my $struct = shift; my $file = $p->{file}; my @subs; for my $name (@{ $p->{order} }){ push @subs, grep {$name eq $_} keys %{ $struct->{$file}{subs} }; } return \@subs; }; } #### sub _engine { trace() if $ENV{TRACE}; my $self = shift; my $p = shift; my $struct = shift; my $engine = defined $p->{engine} ? $p->{engine} : $self->{params}{engine}; if (not $engine or $engine eq ''){ return $struct; } my $cref; if (not ref($engine) eq 'CODE'){ # engine is a name my $engine_module = $self->{namespace} . "::Engine"; my $compiler = $engine_module->new; # engine isn't in the dispatch table if (! $compiler->exists($engine)){ confess "engine '$engine' is not implemented.\n"; } eval { $cref = $compiler->{engines}{$engine}->(); }; # engine has bad func val in dispatch table, but key is ok if ($@){ $@ = "\n[Devel::Examine::Subs speaking] " . "dispatch table in Devel::Examine::Subs::Engine " . "has a mistyped function as a value, but the key is ok\n\n" . $@; confess $@; } } if (ref($engine) eq 'CODE'){ $cref = $engine; } if ($self->{params}{engine_dump}){ my $subs = $cref->($p, $struct); print Dumper $subs; exit; } return $cref; } #### sub all { trace() if $ENV{TRACE}; my $self = shift; my $p = $self->_params(@_); $self->{params}{engine} = 'all'; $self->run($p); } #### sub run { trace() if $ENV{TRACE}; my $self = shift; my $p = shift; $self->_config($p); $self->_run_end(0); my $struct; if ($self->{params}{directory}){ $struct = $self->_run_directory; } else { $struct = $self->_core; $self->_write_file if $self->{write_file_contents}; } $self->_run_end(1); return $struct; } #### my $engine = $self->_engine($p, $subs); if ($self->{params}{engine}){ $subs = $engine->($p, $subs); $self->{write_file_contents} = $p->{write_file_contents}; }