[Cascavel-pm] IPC::Open3 comes to the rescue! (Was: Re: Print Loading ao executar system)

Alceu Rodrigues de Freitas Junior glasswalk3r em yahoo.com.br
Sábado Dezembro 13 03:34:34 PST 2008


++ Daniel

Esses dias eu vi no Calendário do Perl (desculpem pela falta de 
referências) um módulo chamado IPC::Open3::Poll ou algo assim. Faz a 
mesma coisa que o IPC::Open3 mas faz leitura assíncrona dos dados (o que 
talvez seja muito mais sofisticado que a Patty precisa).

Aproveitando o enorme gancho, alguém aí já deu uma espiada em algo 
parecido aos projetos Cometd ou Juggernaut (Java e Ruby, 
respectivamente) para Perl? Eu sei que tem o Perlbal, mas ele não foi 
desenvolvido para a mesma aplicação.

[]'s
Alceu

Daniel Ruoso escreveu:
> Em Ter, 2008-12-09 às 03:35 -0800, Patty Silva escreveu:
>   
>> Pessoal, 
>> Tem como eu imprimir na tela "Loading ................." quando
>> executa o system??
>>     
>
> Olá,
>
> Pessoal, eu tenho me mantido meio calado ultimamente, mas vendo esse
> thread enorme sem ninguem dar a solução para um problema que, precisamos
> reconhecer, não é "de iniciante", resolvi dar a solução...
>
> A resposta curta é: "Não use system".
>
> A resposta longa é:
>
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> use Symbol;
> # essa linha define símbolos para os três filehandles,
> # acho que eu vi isso pela primeira vez no PBP
> my ($wtr, $rdr, $err) = map { gensym } 1..3;
>
> use IPC::Open3;
> my $pid = open3($wtr, $rdr, $err,
>                 'ls', '-la');
>
> # considerando que o comando não recebe nada pelo stdin
> close $wtr;
>
> # usar o IO::Handle é legal porque ele dá uma visão OO sobre
> # os filehandles, o que facilita algumas coisas...
> use IO::Handle;
> # por exemplo:
> $_->blocking(0) for ($rdr, $err);
> STDOUT->autoflush(1);
>
> # usar o IO::Select também é legal, porque te permite acompanhar
> # filehandles de uma maneira mais esperta
> use IO::Select;
> my $sel = IO::Select->new($rdr, $err);
>
> # vamos fazer um loop, e ver se o comando escreveu alguma coisa,
> # se ele não escrever em 1 segundo, imprimimos um "."
> while (1) {
>   my @ready = $sel->can_read(1000);
>   foreach my $io (@ready) {
>     my $type = $io == $rdr ? '[STDOUT]' : '[STDERR]';
>
>     # Como estamos fazendo leitura não bloqueante, não devemos
>     # usar <$io>...
>     if (read $io, my $buf, 1024) {
>       print $type, ' ', $buf, $/;
>     } else {
>       # se read retornar 0 ou undef, é porque acabou o arquivo ou tem
>       # algum erro no filehandle, então vamos tirar do select.
>       $sel->remove($io);
>     }
>   }
>
>   # imprime o pontinho...
>   print '.' unless @ready;
>
>   # sai se não tem mais nenhum filehandle
>   last unless scalar $sel->handles;
> };
>
>
> # espera o processo sair de verdade;
> waitpid $pid, 0;
>
> __END__
>
>
> e é isso aí...
>   

-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/cascavel-pm/attachments/20081213/621bd5c8/attachment.html>


Mais detalhes sobre a lista de discussão Cascavel-pm