Blabos++
2014-02-28 14:49 GMT-03:00 Geraldo Netto <geraldone...@gmail.com>: > Opa! > > Boas dicas Buss e Blabos!!! > Fico devendo a pizza! :) > > Vou melhorar aqui o que eu já tenho e vamos conversando! > > Sobre outros módulos, eu realmente não quero tentar instalar e etc > porque eu sei que eu não vou conseguir mexer nesse servidor > > mesmo que o POC funcione, acho difícil que alguém me autorize a mexer > (instalar um módulo) em um servidor sem suporte do fornecedor (tenho > um dinossauro de Unix que mexe nele quando as coisas explodem e olhe > lá...) > > E mesmo com a possível dificuldade de manipulação de datas com a api do > posix > eu prefiro ela que ter que calcular as coisas todas em shell, eheheh :) > > Além do mais, eu acho que eu posso pegar alguns atalhos no sentido de > limpar a forma como eu to desenhando esse script > > Outros incrementos virão! :) > > > Força e Honra Senhores! > > Geraldo Netto > Sapere Aude => Non dvcor, dvco > São Paulo, Brasil, -3gmt > site: http://exdev.sf.net/ > > > 2014-02-28 14:28 GMT-03:00 Blabos de Blebe <bla...@gmail.com>: > > Eu tava escrevendo uma resposta, mas o buss foi mais rápido então > cortando > > os overlaps, com bastante licença poética: > > > > Primeiro as masturbações estilísticas: > > > >> #!/usr/bin/perl > > > > Eu prefiro usar: > > > > #!/usr/bin/env perl > > > > Porque, se o script for usado num ambiente onde espera-se outro perl que > não > > o do /usr/bin, como num perlbrew por exemplo, você não fica com a versão > > antiga do perl hardcoded. > > > > Mas no seu caso, não acredito que vá ocorrer esse caso de uso, então pode > > ficar como está, numa boa. Não está errado. > > > >> use strict; > >> use warnings; > > > > Bom garoto! > > > > Ambas as pragmas são mandatórias, caso você esteja escrevendo algo > > minimamente decente. Tem gente que gosta também do: > > > > use diagnostics; > > > > que te dá ainda mais informação em caso de problemas. > > > >> use POSIX; > > > > Aqui, a explicação longa é longa (call @garu), mas resumidamente, você > está > > importando alguns símbolos desnecessários automaticamente pro namespace > > corrente. > > > > Isso é completamente irrelevante pro seu caso, mas vc poderia fazer > assim: > > > > use POSIX (); > > > > que significa, adicione o módulo POSIX mas não importe nenhum símbolo. Ou > > ainda: > > > > use POSIX qw{ strftime } > > > > que significa, adicione o módulo POSIX e importe somente o símbolo > (função) > > strftime. Nesse caso, ao usar a sub, vc não precisaria mais prefixar com > > POSIX:: > > > > Do meu ponto de vista, tanto faz: > > > > use POSIX (); > > POSIX::strftime(); > > > > ou > > > > use POSIX qw( strftime ); > > strftime(); > > > > > > Eu também prefiro nomear_funcoes_em_minusculas_com_underscore do que > > comCameCaseIgualAoJava. > > > > > > *** > > > > > > Sobre a sua dúvida na captura e tratamento dos parâmetros tem algumas > > sutiliezas que podem levar a erros. > > > > *** Primeiramente, acessar elementos versus acessar slice de um array > > > > A forma de acessar um escalar dentro de um array é indicando que ele é um > > escalar, e dizendo qual índice você quer, ou seja, para acessar o > terceiro > > elemento do array foo, temos: > > > > my $elemento = $foo[ 2 ]; > > > > que significa mais ou menos, pegue o escalar ($) que está no array foo na > > posição 3 (índice 2). > > > > Quando você faz: > > > > $a = @_[3]; > > > > Você está pedindo, me dê um array (@) contendo os elementos que estão > "nos > > índices" 3 do array _. Isso é um slice, que normalmente é usado pra pegar > > pedaços de array. > > > > No seu caso, como você tá pedidndo uma lista com apenas um elemento, > também > > funciona mas experimente testar o seguinte: > > > > my $a = @_[1,2]; > > > > > > Dito isso, quando vc faz: > > > > $foo = @_[0], a menos que você saiba exatamente o que está fazendo, isso > > está errado. Não é questão de estilo aqui. O correto seria: > > > > $foo = $_[0]; ## Me dê o escalar que está no índice zero do array _ > > > > > > *** Acessando parâmetros de funções > > > > Os parâmetros de funções são passados no array _, ou seja, @_. > > > > Ele faz aliasing das variáveis passadas, ou seja, ao lidar com $_[] > > diretamente, você pode causar efeitos colaterais externos inesperados. > > > > Por exemplo, nesse oneliner apenas para efeitos didáticos: > > > > perl -e 'sub foo { $_[0]++ } $a=1; foo($a); print $a . $/' > > > > Por isso é boa prática criar uma cópia local dos argumentos dentro da > > função. Isso pode ser feito de varias maneiras, conforme o caso: > > > > > > ## Crie uma cópia do @_ chamada @args; > > my @args = @_; > > > > > > ## Crie uma lista com dois escalares, atribua os dois primeiros > elementos do > > @_ a cada um deles e descarte o resto; > > my ( $first, $second ) = @_; > > > > > > ## Crie uma lista contendo dois escalares, um array, guarde os dois > > primeiros elementos de @_ nos escalares e o resto no array @tail > > my ( $first, $second, @tail ) = @_ > > > > > > ## Remova o primeiro elemento de @_ e coloque-o no escalar criado > > my $first = shift; ## Equivalente a my $first = shift @_; > > my $second = shift; # Pegue o "novo primeiro" elemento de @_ > > > > A vesão com shift remove definitivamente o primeiro elemento do array. O > > segundo elemento passa a ser o primeiro, e assim sucessivamente. O > tamanho > > do array é reduzido em 1. > > > > Minhas fontes não confiáveis apontam que a versão com shift é menos > > eficiente. Por favor me corrijam quem estiver com as fontes corretas. > > > > Eu prefiro usar as duas primeiras formas. my @args = @_; ou my ( $first, > > $second ) = @_; > > > > *** > > > > Conforme o buss apontou, separe uma instrução por linha: > > > > sub calcularDeslocamentoAno { > > my ( $ano ) = @_; > > > > die 'ano invalido' > > unless defined $ano; > > > > return $ano > 99 ? $ano - 1900 : $ano; > > } > > > > Veja como fica mais claro pro próximo cara que for dar manutenção nisso. > > > > *** > > > > Use qx ao invés de ` pra invocar comandos externos > > > > sub calcularDiaInicioHorarioVerao { > > my $dia_inicio = qx{ cal 10 2013 | tail -4 | head -1 | cut -d' ' -f7 > }; > > } > > > > Considerações finais: > > > > 1) Seu código está até bem razoável. Compartimentarizado em funções que > só > > fazem uma coisa. Ele está claro no que ele pretende fazer. Isso é muito > bom. > > Té melhor que muito programador "experiente" que tem por aí. > > > > 2) Tem uns requintes de Perl 4, mas fazendo os ajustes indicados, que não > > são nada complicados, seu código vai rejuvenecer uns 20 anos!!! > > > > 3) Não é porque você executa comandos do Shell que o seu código Perl fica > > ruim. Nada disso. É parte da linguagem e perfeitamente normal, > > principalmente, porque você deixa bem claro o que você está fazendo e de > > forma organizada. Acessar o shell continua sendo elegante. > > > > Feio é fazer algazarra. > > > > Existem módulos pra rodar comandos externos, com mil funcionalidades, mas > > acredito que não são necessários no seu caso. > > > > 4) DateTime, pode se mais indicado do que calcular datas na mão, mas ele > não > > é "Core" (http://perldoc.perl.org/corelist.html), portanto pode ser > difícil > > de instalar no seu sistema com ambiente restrito. Você tem que medir se o > > custo de instalar vale o benefício que ele fornece ou ainda se o risco do > > seu código falhar é alto ou baixo. Isso é uma análise sua. > > > > Eventualmente eu pelo menos comentaria no código que o DateTime poderia > ser > > uma solução mais adequada. Vai que o ambiente muda no futuro e ele possa > ser > > instalado mais facilmente. > > > > 5) Tente escrever testes automatizados que validem a sua aplicação. > > > > > > > > Bom, espero que tenhamos te ajduado. Qualquer coisa avisa. > > > > > > []'s > > > > > > > > > > > > > > > > > > > > 2014-02-28 13:31 GMT-03:00 Bruno Buss <bruno.b...@gmail.com>: > > > >> Oi Geraldo, > >> > >> Respostas inline :-) > >> > >> > >> 2014-02-28 11:59 GMT-03:00 Geraldo Netto <geraldone...@gmail.com>: > >> > >>> Bom Dia Pessoal! > >>> > >>> Consegui evoluir no código com a api do posix mesmo > >>> crio as datas com POSIX::strftime > >>> e calculo o horário de verão pegando a saida do comando cal no shell > >>> > >>> yep, eu sei que é feito, mas resolve o meu problema de um jeito > rápido... > >>> por hora, a idéia é só gerar o "okay" da gerencia p/ matar umas 4 > >>> versões shell que fazem o mesmo trabalho, mas precisam de alguns > >>> parâmetros diferentes e alguma intervenção humana especificamente no > >>> período de horário de verão > >> > >> > >> Thumbs up por resolver o problema! :D > >> > >> Entretanto, o que a galera quer passar aqui, e' que mesmo que você > >> realmente acredite que esta resolvendo seu problema de forma simples e > >> rápida agora... não esta'. Ou melhor, o jeito rápido agora > *provavelmente* > >> ira' te causar uma baita dor de cabeça soon(tm). > >> > >> Tente utilizar o DateTime, e' uma solução ordens de grandeza melhor e > não > >> e' tao difícil assim :-) > >> > >>> > >>> > >>> a minha dúvida é primária, suponho... > >>> mas eu não entendi o porque usar o shift > >>> se eu posso verificar com o defined() se o @_[<número>] está definido? > >> > >> > >> O shift serve para voce retirar e retornar o 1o elemento da lista de > >> argumentos/parâmetros que foi passada para sua função. > >> > >> E' uma das formas idiomáticas de se fazer isso, a outra seria "my ($v_a, > >> $v_b, $v_c) = @_;". > >> Pessoalmente prefiro com shift :-) > >> > >>> > >>> > >>> Aceito sugestões e Mais uma vez, Valeu mesmo pela força! :P > >>> > >>> > >>> BTW, código todo a seguir: > >>> > >>> #!/usr/bin/perl > >>> > >>> use strict; > >>> use warnings; > >>> > >>> use POSIX; > >>> > >>> > >>> # a inicia a data em 1900 entao, se for passado 95 => 1995 > >>> sub calcularDeslocamentoAno { > >>> die "ano invalido" unless defined(@_[0]) && return ($_[0] > 99 ? > >>> $_[0] - 1900 : $_[0]); > >>> } > >> > >> > >> Então para você o ano 50 e' o mesmo que o ano 1950? :P > >> Ou se eu passar para você o ano 1800, ele retorna -100. > >> > >> Outra coisa, você realmente não precisa colocar o return na mesma linha > do > >> die... > >> Por exemplo: > >> > >> sub calcularDeslocamentoAno{ > >> my $ano = shift; > >> > >> #Rejeitando coisas que nossa funcao nao sabe tratar. > >> die "ano invalido" unless defined $ano && $ano >= 1900; > >> > >> return $ano - 1900; > >> } > >> > >>> > >>> > >>> sub criarData { > >>> die "parametros invalidos" unless (defined(@_[0]) && > >>> defined(@_[1]) && defined(@_[2])); > >>> #Usage: POSIX::strftime(fmt, sec, min, hour, mday, > >>> mon, year, wday = -1, yday = -1, isdst = -1) > >>> return POSIX::strftime("%Y,%m,%d", 0, 0, 0, @_[0], (@_[1] -1), > >>> &calcularDeslocamentoAno(@_[2]), 0, 0); > >>> } > >> > >> > >> Idealmente você estaria tratando: > >> * Se o 1o parâmetro e' um dia que esta' no mês (posso tentar usar > stftime > >> passando o dia 31 de Fev?) > >> * Se o 1o parâmetro e' um dia valido at all (dia igual a 44 por > exemplo). > >> * Lembrar que o dia e o mês são 0-based, ou seja Janeiro => 0, Fev => 1, > >> etc. > >> ... > >> > >> Voce tambem poderia fazer: > >> sub criarData { > >> my ($dia, $mes, $ano) = @_; > >> die "parametros invalidos" unless defined $dia && > >> defined $mes && > >> defined $ano; > >> ... > >> } > >> > >> Detalhe: O DateTime tem funções de formatação de data tao boas quanto > ;-) > >> > >>> > >>> > >>> sub calcularDiaInicioHorarioVerao { > >>> my $dia_inicio = `cal 10 2013 | tail -4 | head -1 | cut -d' ' -f7`; > >>> } > >>> > >>> sub calcularDiaFimHorarioVerao { > >>> my $dia_fim = `cal 2 2014 | tail -4 | head -1 | cut -d' ' -f7`; > >>> } > >> > >> > >> Alguém já disse em substituir isso tudo por DateTime? :P > >> > >>> > >>> > >>> sub trim { > >>> my $s = shift; > >>> $s =~ s/^\s+|\s+$//g; > >>> return $s; > >>> } > >>> > >>> print &criarData(2, 5, 2014); > >>> print &trim($dia_inicio); > >>> print &trim($dia_fim); > >> > >> > >> Não sei exatamente qual Perl você ta usando, mas acredito que não e' > >> necessário prefixar as chamadas de funções com &. Inclusive isso e' > >> considerado não legal hoje em dia :-) > >> > >> [ ]'s > >> > >> PS: Utilize uma ferramenta tipo pastebin ou Gist (do GitHub) para > copiar e > >> enviar codigos em listas de e-mail :-) > >> > >>> > >>> > >>> Geraldo Netto > >>> Sapere Aude => Non dvcor, dvco > >>> São Paulo, Brasil, -3gmt > >>> site: http://exdev.sf.net/ > >>> > >>> 2014-02-26 23:41 GMT-03:00 Geraldo Netto <geraldone...@gmail.com>: > >>> > Opa! > >>> > > >>> > Tudo okay Pessoal? > >>> > > >>> > Eu sou o Geraldo, um ghost reader da SPPM (e algumas outras PMs) > >>> > e eu ando trabalhando vagarosamente num projetinho > >>> > que eu dependo de verificação do horário de verão > >>> > > >>> > A idéia é separar o ano em 3 partes: > >>> > > >>> > fim do horário de verão (terceiro domingo de fevereiro) > >>> > fora do horário de verão > >>> > início do horário de verão (terceiro sábado de fevereiro) > >>> > > >>> > E baseado nisso, lançar um shell que vai receber o timezone, data de > >>> > início e de fim > >>> > p/ fazer a coleta de dados pelo hp openview (comando ovpmbatch) > >>> > > >>> > Só que... > >>> > -eu tenho um servidor tru64 (sem suporte) > >>> > -rodando perl 5.8 (2002 pelo o que o version diz...) > >>> > -sem sudo/root/possibilidade de instalação de pacotes de terceiros > >>> > -<inclua-aqui-todas-as-limitações-que-vocês-imaginarem-de-infra> > >>> > -meu "core business" é análise de desempenho de software, > >>> > então o código não pode ser muito "perlish" > >>> > porque alguém pode precisar dar manutenção depois de mim > >>> > > >>> > Embora eu ainda não tenha código real (só comecei a brincar) > >>> > Eu estou pensando em ir com a api do posix, especificamente a > >>> > função/método strftime > >>> > > >>> > Eventualmente vocês teriam alguma sugestão? > >>> > > >>> > > >>> > Grande Abraço! > >>> > > >>> > Geraldo Netto > >>> > Sapere Aude => Non dvcor, dvco > >>> > São Paulo, Brasil, -3gmt > >>> > site: http://exdev.sf.net/ > >>> =begin disclaimer > >>> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/ > >>> SaoPaulo-pm mailing list: SaoPaulo-pm@pm.org > >>> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm> > >>> =end disclaimer > >> > >> > >> > >> > >> -- > >> Bruno C. Buss > >> http://www.brunobuss.net > >> > >> > >> 2014-02-28 11:59 GMT-03:00 Geraldo Netto <geraldone...@gmail.com>: > >> > >>> Bom Dia Pessoal! > >>> > >>> Consegui evoluir no código com a api do posix mesmo > >>> crio as datas com POSIX::strftime > >>> e calculo o horário de verão pegando a saida do comando cal no shell > >>> > >>> yep, eu sei que é feito, mas resolve o meu problema de um jeito > rápido... > >>> por hora, a idéia é só gerar o "okay" da gerencia p/ matar umas 4 > >>> versões shell que fazem o mesmo trabalho, mas precisam de alguns > >>> parâmetros diferentes e alguma intervenção humana especificamente no > >>> período de horário de verão > >>> > >>> a minha dúvida é primária, suponho... > >>> mas eu não entendi o porque usar o shift > >>> se eu posso verificar com o defined() se o @_[<número>] está definido? > >>> > >>> Aceito sugestões e Mais uma vez, Valeu mesmo pela força! :P > >>> > >>> > >>> BTW, código todo a seguir: > >>> > >>> #!/usr/bin/perl > >>> > >>> use strict; > >>> use warnings; > >>> > >>> use POSIX; > >>> > >>> > >>> # a inicia a data em 1900 entao, se for passado 95 => 1995 > >>> sub calcularDeslocamentoAno { > >>> die "ano invalido" unless defined(@_[0]) && return ($_[0] > 99 ? > >>> $_[0] - 1900 : $_[0]); > >>> } > >>> > >>> sub criarData { > >>> die "parametros invalidos" unless (defined(@_[0]) && > >>> defined(@_[1]) && defined(@_[2])); > >>> #Usage: POSIX::strftime(fmt, sec, min, hour, mday, > >>> mon, year, wday = -1, yday = -1, isdst = -1) > >>> return POSIX::strftime("%Y,%m,%d", 0, 0, 0, @_[0], (@_[1] -1), > >>> &calcularDeslocamentoAno(@_[2]), 0, 0); > >>> } > >>> > >>> sub calcularDiaInicioHorarioVerao { > >>> my $dia_inicio = `cal 10 2013 | tail -4 | head -1 | cut -d' ' -f7`; > >>> } > >>> > >>> sub calcularDiaFimHorarioVerao { > >>> my $dia_fim = `cal 2 2014 | tail -4 | head -1 | cut -d' ' -f7`; > >>> } > >>> > >>> sub trim { > >>> my $s = shift; > >>> $s =~ s/^\s+|\s+$//g; > >>> return $s; > >>> } > >>> > >>> print &criarData(2, 5, 2014); > >>> print &trim($dia_inicio); > >>> print &trim($dia_fim); > >>> > >>> Geraldo Netto > >>> Sapere Aude => Non dvcor, dvco > >>> São Paulo, Brasil, -3gmt > >>> site: http://exdev.sf.net/ > >>> > >>> 2014-02-26 23:41 GMT-03:00 Geraldo Netto <geraldone...@gmail.com>: > >>> > Opa! > >>> > > >>> > Tudo okay Pessoal? > >>> > > >>> > Eu sou o Geraldo, um ghost reader da SPPM (e algumas outras PMs) > >>> > e eu ando trabalhando vagarosamente num projetinho > >>> > que eu dependo de verificação do horário de verão > >>> > > >>> > A idéia é separar o ano em 3 partes: > >>> > > >>> > fim do horário de verão (terceiro domingo de fevereiro) > >>> > fora do horário de verão > >>> > início do horário de verão (terceiro sábado de fevereiro) > >>> > > >>> > E baseado nisso, lançar um shell que vai receber o timezone, data de > >>> > início e de fim > >>> > p/ fazer a coleta de dados pelo hp openview (comando ovpmbatch) > >>> > > >>> > Só que... > >>> > -eu tenho um servidor tru64 (sem suporte) > >>> > -rodando perl 5.8 (2002 pelo o que o version diz...) > >>> > -sem sudo/root/possibilidade de instalação de pacotes de terceiros > >>> > -<inclua-aqui-todas-as-limitações-que-vocês-imaginarem-de-infra> > >>> > -meu "core business" é análise de desempenho de software, > >>> > então o código não pode ser muito "perlish" > >>> > porque alguém pode precisar dar manutenção depois de mim > >>> > > >>> > Embora eu ainda não tenha código real (só comecei a brincar) > >>> > Eu estou pensando em ir com a api do posix, especificamente a > >>> > função/método strftime > >>> > > >>> > Eventualmente vocês teriam alguma sugestão? > >>> > > >>> > > >>> > Grande Abraço! > >>> > > >>> > Geraldo Netto > >>> > Sapere Aude => Non dvcor, dvco > >>> > São Paulo, Brasil, -3gmt > >>> > site: http://exdev.sf.net/ > >>> =begin disclaimer > >>> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/ > >>> SaoPaulo-pm mailing list: SaoPaulo-pm@pm.org > >>> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm> > >>> =end disclaimer > >> > >> > >> > >> > >> -- > >> Bruno C. Buss > >> http://www.brunobuss.net > >> > >> =begin disclaimer > >> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/ > >> SaoPaulo-pm mailing list: SaoPaulo-pm@pm.org > >> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm> > >> =end disclaimer > >> > > > > > > =begin disclaimer > > Sao Paulo Perl Mongers: http://sao-paulo.pm.org/ > > SaoPaulo-pm mailing list: SaoPaulo-pm@pm.org > > L<http://mail.pm.org/mailman/listinfo/saopaulo-pm> > > =end disclaimer > > > =begin disclaimer > Sao Paulo Perl Mongers: http://sao-paulo.pm.org/ > SaoPaulo-pm mailing list: SaoPaulo-pm@pm.org > L<http://mail.pm.org/mailman/listinfo/saopaulo-pm> > =end disclaimer > -- Saravá, Renato CRON http://www.renatocron.com/blog/ @renato_cron <http://twitter.com/#!/renato_cron>
=begin disclaimer Sao Paulo Perl Mongers: http://sao-paulo.pm.org/ SaoPaulo-pm mailing list: SaoPaulo-pm@pm.org L<http://mail.pm.org/mailman/listinfo/saopaulo-pm> =end disclaimer