Breno G. de OliveiraPublicado em 01/03/2010
Há casos em que nossos aplicativos em Catalyst são tão extensos, com regras de negócio tão complexas, que podemos nos sentir um pouco soterrados pela enorme quantidade de componentes e correlações. Ou talvez fiquemos tão concentrados em uma pequena parte que acabamos perdendo a visão geral do aplicativo. Nada tema!
O mundo Perl oferece uma série de ferramentas de visualização. No artigo de hoje daremos uma olhada mais de perto em três delas, uma para cada elemento do MVC, usando uma instalação padrão do MojoMojo para ilustrar os resultados.
O incrível módulo SQL::Translator pode facilmente mostrar como o esquema de seu modelo se parece, diretamente do esquema de seu banco de dados - seja MySQL, Oracle, PostreSQL, SQLite, ou qualquer um dos diversos parsers de bancos de dados disponíveis. Basta especificá-lo no campo 'from', escolhendo 'GraphViz' como destino.
use SQL::Translator;
my $translator = SQL::Translator->new(
from => 'MySQL',
to => 'GraphViz',
) or die SQL::Translator->error;
$translator->translate( 'MySchema.sql' );
Se sua aplicação Catalyst usa o popular DBIx::Class (DBIC), você pode
obter informações sobre o banco diretamente dos módulos de esquema! Para
isso, escolha 'SQL::Translator::Parser::DBIx::Class
' como 'parser
',
e passe o esquema já carregado no parâmetro 'parser_args
'. O código abaixo
mostra como fazer isso, incluindo algumas personalizações da imagem de
saída através do parâmetro 'producer_args
'
use SQL::Translator;
use MyApp::Schema; # substitua pelo nome da classe de seu esquema
my $schema = MyApp::Schema->connect;
my $translator = SQL::Translator->new(
parser => 'SQL::Translator::Parser::DBIx::Class',
parser_args => { package => $schema },
producer => 'Diagram',
producer_args => {
out_file => 'schema.png',
output_type => 'png',
title => 'Meu Model',
},
) or die SQL::Translator->error;
$translator->translate;
Você pode até mesmo criar uma action do Catalyst que gera o diagrama do projeto atual:
sub schema : Local {
my ( $self, $c ) = @_;
my $translator = SQL::Translator->new(
parser => 'SQL::Translator::Parser::DBIx::Class',
data => $c->model('DB')->schema,
producer => 'Diagram',
producer_args => {
output_type => 'png',
title => 'Model da App',
},
) or die SQL::Translator->error;
$c->res->content_type('image/png');
$c->res->body( $translator->translate );
}
O resultado? Veja por si mesmo :)
Talvez o 'model' não seja seu (único) problema, e a quantidade de controllers e actions de sua aplicação cresceu tanto que precisam de mais documentação, um guia de referência rápida, ou até mesmo alguma refatoração de código. Embora a estrutura de controllers do Catalyst costume levar a uma boa organização por parte do programador, acidentes de percurso podem ocorrer.
Felizmente para nós, Franck Cuny criou um módulo muito conveniente chamado CatalystX::Dispatcher::AsGraph, que exibe suas actions privadas em um belo grafo direcionado (digrafo), com apenas algumas linhas de código!
use CatalystX::Dispatcher::AsGraph;
my $graph = CatalystX::Dispatcher::AsGraph->new(
appname => 'MyApp',
output => 'minhas_actions.png',
);
$graph->run;
Se o código acima for executado com sucesso, a variável $graph
contém
um objeto Graph::Easy
contendo o grafo das actions. Podemos
usar o programa dot
para exportar nosso grafo para um arquivo png:
if ( open( my $png, '|-', 'dot -Tpng -o ' . $graph->output ) ) {
print $png $graph->graph->as_graphviz;
close $png;
}
Um programa de exemplo, que vem com a distribuição do módulo, faz
exatamente isso, mas utiliza o módulo MooseX::GetOpt
para deixar
que o usuário especifique os parâmetros do módulo como opções de linha
de comando.
Nota: Khisanth mencionou que, como esse módulo utiliza MooseX::Declare
e não possui informações de pacote, o indexador do CPAN não o registra,
e a shell do CPAN não o encontra. Até que o autor corrija isso, você precisará
usar o caminho completo para instalar a distribuição (por exemplo, digitando
install FRANCKC/CatalystX-Dispatcher-AsGraph-0.02.tar.gz
na shell do
CPAN), ou obter o .tar.gz diretamente da web.
Assim como o schema e as actions, você pode ver toda a sua estrutura de templates como um grafo direcionado. O módulo Template::AsGraph mode ser facilmente chamado para gerar esses dados a partir de qualquer template:
use Template::AsGraph;
my $graph = Template::AsGraph->graph('meu_template.tt2');
A variável $graph
retornada é um objeto Graph::Easy
que pode ser
transformado em uma imagem PNG exatamente como você fez com o gráfico
do Controller:
if ( open( my $png, '|-', 'dot -Tpng -o grafo_do_template.png' ) ) {
print $png $graph->graph->as_graphviz;
close $png;
}
Agora, se você precisa entender como seus templates se relacionam
entre si, então seu fluxo de exibição é tão intricado que você
provavelmente carrega diferentes partes dinamicamente, conforme os
dados passados pelo Controller. Não se preocupe: o método graph()
também pode receber configurações do TT como segundo argumento, e
variáveis como terceiro:
use Template::AsGraph;
my %config = (
INCLUDE_PATH => 'root/src/',
START_TAG => '<+', end_tag=""> '+>',
PLUGIN_BASE => 'MyApp::Template::Plugin',
PRE_PROCESS => 'header',
);
my %vars = (
foo => 'bar',
bar => 'baz',
);
+',>
Como alternativa se você tem acesso a um objeto de contexto do Catalyst,
podemos ter maior precisão passando nossas variáveis para os templates
exatamente como o View::TT
faz:
my %vars = ( %{ $c->stash() },
c => $c,
base => $c->req->base,
name => $c->config->{name}
);
my $graph = Template::AsGraph->graph('meu_template.tt2', \%config, \%vars);
Esperamos que, ao gerar e analisar os gráficos de seu schema, actions e templates, você consiga um entendimento ainda maior da aplicação em que está trabalhando. Lembre-se do que fez certo, revise o que pode melhorar, e aja em cima do que encontrou. Dessa forma, você certamente se tornará um desenvolvedor melhor, que é o espírito dos artigos deste calendário :)
Breno G. de Oliveira <garu@cpan.org>
Bogdan Lucaciu <bogdan@sinapticode.ro>
Traduzido e adaptado para o português por Breno G. de Oliveira a partir do original em inglês.