[SP-pm] Fix-DateTime

Eden Cardim eden at insoli.de
Wed Jan 9 03:35:55 PST 2013


The following message is a courtesy copy of an article
that has been posted to gmane.comp.lang.perl.perl-mongers.saopaulo as well.

>>>>> "Tiago" == Tiago Peczenyj <tiago.peczenyj-Re5JQEeQqe8AvxtiuMwx3w em public.gmane.org> writes:

    Tiago> Oi Galera Me foi passado um exercicio bem interessante
    Tiago> sobre "corrigir" um comportamento da classe DateTime.

    Tiago> O default time zone da classe DateTime é UTC, porém alguem
    Tiago> ignorou isso e desenvolveu uma boa quantidade de coisas,
    Tiago> colocou em produção, etc, só descobriu q tinha algo errado
    Tiago> quando alguns testes falhavam em alguns horarios
    Tiago> específicos. No caso algumas coisas estavam em EST (como o
    Tiago> banco de dados) e para resolver isso "logo", no lugar de
    Tiago> alterar o sistema (por medinho, tempo, etc) resolveram
    Tiago> fazer algo mais grosseiro.

    Tiago> A minha solução ficou assim:

    Tiago> https://github.com/peczenyj/Fix-DateTime

    Tiago> Acho que esta menos pior do que poderia ser, mas ainda
    Tiago> fede. Não é exatamente um Fix, mas resolve algumas coisas.

Algumas considerações:

- Não precisa mudar todos os métodos, só um wrapper no ->new() já
  basta. Com esse tipo de alteração, quanto menos intrusivo você for,
  melhor, vai que alguém decide mudar algo nos internals e colocar o
  new numa classe base, aí o DateTime::new vai deixar de existir e vai
  quebrar o wrapper.

- Apesar do Michael Schwern achar bacana o uso de "goto ⊂" porque
  faz parecer que o wrapper não está lá, eu detesto essa construção
  exatamente por esse motivo. Essa forma de invocação do goto
  sobrescreve a chamada atual da stack com a nova chamada, em algumas
  situações isso pode virar um pesadelo de depuração quando outra
  pessoa pegar o código e não entender porque raios o time_zone está
  em EST quando a doc diz que é UTC (logo em seguida ele vai começar a
  programar em Java, dizendo que Perl é uma merda).

- É possível que o teu bloco BEGIN execute antes do BEGIN implícito do
  use DateTime em algum outro lugar do seu código, por isso você
  precisa carregar o DateTime explicitamente.

Eu implementaria assim:

use DateTime;
our ENABLE = 1;
our %defaults = (time_zone => 'EST');

BEGIN {
  if($ENABLE) {
    my $sub = DateTime->can('new')
      or die "AVISO: Método DateTime->new sumiu, ISSO VAI QUEBRAR O SISTEMA TODO";
    *DateTime::new = sub {
       my($class, %args) = @_;
       $class->$sub(%defaults, %args);
    };
  }
}

-- 
Eden Cardim -- Insolide Soluções de TI Ltda.
+55 11 9644 8225
http://insoli.de


More information about the SaoPaulo-pm mailing list