Desenvolvimento
Rápido de Programas
 Linha de Comando

      Breno G. de Oliveira
        breno@rio.pm.org
Ferramentas Linha de Comando

 Tradicionais
        ● Exibição de ajuda (“help”)
        ● Parsing de argumentos




 Orientada a comandos
        ● Dispatcher
        ● Help específico

        ● Shell
Dicotomia do Perl



          linguagem
               X
          ferramenta
Perl como ferramenta?

 “Easy things, easy.”

 Com Perl, quase tudo é fácil ;-)

 Sysadmins e pesquisadores sabem disso
 (ou deveriam saber)

 ...e usam Perl diariamente como ferramenta para
 solucionar problemas de forma rápida e eficiente
 (ou deveriam usar)
Problemas com One-liners
(e pequenos programas)


     “escreva e descarte”
     (ou tenha pesadelos para manter)

     Repetição constante

     Baixa escalabilidade e flexibilidade

     *cof*cof* documentação? *cof*cof*
Modelo Tradicional



      Getopt::Long + Pod::Usage



        Eficiente para programas lineares,
               mas não escala bem.
Frameworks


     DRY (Don't Repeat Yourself)

     Flexibilidade

     Escalabilidade

     Documentação

     Testes
Command Line Frameworks


     App::CLI

     App::Cmd

     CLI::Dispatch

     CLI::Framework
App::Rad
App::Rad


     Simples (e fácil) de instalar e usar

     Leve!

     Facilmente extensível

     Integração com one-liners
Meu primeiro programa



     use App::Rad;
     App::Rad->run;
Meu primeiro programa

> ./meuprog.pl
Usage: ./meuprog.pl  command [arguments]

Available Commands:
   help    show syntax and available commands

>
Adicionando versão



     use App::Rad;
     App::Rad->run;
Adicionando versão



     use App::Rad;
     App::Rad->run;

     our $VERSION = '0.1.1-pre-alfa';
Executando novamente

> ./meuprog.pl
meuprog.pl version 0.1.1­pre­alfa
Usage: ./meuprog.pl  command [arguments]

Available Commands:
   help    show syntax and available commands

> ./meuprog.pl ­­version
meuprog.pl version 0.1.1­pre­alfa

>
Criando Comandos

  use App::Rad;
  App::Rad­>run;

  sub hello {
     return “Hello, World!”;
  }
Criando Comandos

> ./meuprog.pl
Usage: ./meuprog.pl  command [arguments]

Available Commands:
   hello
   help    show syntax and available commands

> ./meuprog.pl hello
Hello, World!

>
Criando Comandos Mais Interessantes
 use App::Rad;
 App::Rad­>run;

 sub roll :Help(roll a dice in AdX format) {
    my $c = shift;
    my $value = 0;

    if ( $c­>argv­>[0] =~ m{(d+)d(d+)} ) {
       for (1..$1) {
          $value += int(rand($2) + 1);
       }
    }
    return $value;
 }
Criando Comandos Mais Interessantes

> ./meuprog.pl
Usage: ./meuprog.pl  command [arguments]

Available Commands:
   help   show syntax and available commands
   roll   roll a dice in AdX format

> ./meuprog.pl  roll  3d4
7

>
Argumentos Simples


      @ARGV

      $c->options

      $c->argv

      $c->getopt
Argumentos Explícitos

 sub setup {
      my $c = shift;

      $c­>register_commands({
            cmd1  => { arg1 => { 
                            type      => 'num',
                            condition => sub { $_ < 3 },
                            required  => 1,
                       },
                       arg2 => {
                            type      => 'str'
                       },
                     }
            }
     }
 }
Fluxo do programa
Funções de Controle


       setup()

       pre_process()

       post_process()

       teardown()
Compartilhando dados (stash)
       sub command {
           my $c = shift;
           my $ret = do_something();

             if ( $ret =~ /critical error/ ) {
                 $c->stash->{mail} = 1;
             }
             return $ret;
         }

         sub post_process {
           my $c = shift;

             if ( $c->stash->{mail} ) {
                 # send email alert...
             }
             else {
                 print $c->output . "n";
             }
         }
“include” && “exclude”


   Comandos embutidos

   Manipulação de one-liners!

   Ambos “opt-in”

   use App::Rad qw(include exclude);
“include” && “exclude”

  > perl ­e 'print “FISL!n”'
  FISL!

  > ./meuprog.pl include ­e 'print “FISL!n”'

  > ./meuprog.pl help
  Usage: ./meuprog.pl command [arguments]

  Available Commands:
     cmd1
     include
     help
     exclude
“include” && “exclude”

  > ./meuprog.pl cmd1
  FISL!


  (enquanto isso, em meuprog.pl...)

  sub cmd1 {
     my $c = shift;
     print “FISL!n”;
  }
Exemplos mais convincentes

Pegamos um one-liner “místico”...

> perl ­i ­paF, ­le 'splice @F,1,0,$.;
$_=join “,”,@F'  planilha.csv

Fazemos uma substituição simples...

> ./meuprog.pl include adiciona_coluna
­i ­paF, ­le 'splice @F,1,0,$.; $_=join “,”,@F'

e voilá!

> ./meuprog.pl  adiciona_coluna  planilha.csv
(algumas) funções auxiliares

   commands()

   is_command( NOME )

   register( NOME, CODEREF )

   unregister( NOME )

   load_config( ARQUIVO)
Modo “shell” (REPL)



     use App::Rad;
     App::Rad->run;
Modo “shell” (REPL)



     use App::Rad;
     App::Rad->shell;
Modo “shell” (REPL)

> ./meuprog.pl
meuprog> help
Available Commands:
   help   show syntax and available commands
   quit   exits the program
   roll   roll a dice in AdX format
meuprog> roll 2d10
9
meuprog> quit

>
Plugins!

      Prontos:

           ● TT
           ● ConfigLoader




      Em andamento:

           ● Log4perl
           ● Daemon

           ● ...?
Extensões!



         MooseX::App::Rad
             (em andamento)
Módulos interessantes de usar

     Sysadm::Install

     PUNC (Perl Unified Network Controller)

     Net::Server

     IPC::Cmd

     IO::Prompt

     Term::Menu
Onde encontrar


  Código estável+documentação: CPAN

  Bleeding-edge: http://github.com/garu/App-Rad/

  Discussão: #app-rad em irc.perl.org
Compartilhe sua idéia!




       Estaremos no stand de Perl
         durante todo o evento!
Obrigado!
Dúvidas?
  breno@rio.pm.org

Desenvolvimento Rápido de Programas Linha de Comando