Gráficos de sua Aplicação Catalyst

Breno G. de Oliveira
Publicado em 01/03/2010

Gráficos de sua Aplicação Catalyst

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.

Gráficos do 'Model'

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 :)

schema padrao do MojoMojo

Gráficos do 'Controller'

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.

actions privadas do MojoMojo

Gráficos da 'View'

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);

um dos templates do MojoMojo

Conclusão

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 :)

AUTOR

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.

blog comments powered by Disqus