[SP-pm] Perl e horário de verão

Renato Santos renato.cron at gmail.com
Fri Feb 28 09:50:51 PST 2014


Blabos++


2014-02-28 14:49 GMT-03:00 Geraldo Netto <geraldonetto at 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 <blabos at 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
>> > 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.buss at gmail.com>:
> >
> >> Oi Geraldo,
> >>
> >> Respostas inline :-)
> >>
> >>
> >> 2014-02-28 11:59 GMT-03:00 Geraldo Netto <geraldonetto at 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 <geraldonetto at 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 at 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 <geraldonetto at 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 <geraldonetto at 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 at 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 at 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 at 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 at 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>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20140228/e972cda8/attachment-0001.html>


More information about the SaoPaulo-pm mailing list