Parece haver uma certa fixação entre os programadores, principalmente os menos experientes, em quantas linhas de código são necessárias para resolver determinado problema.
Às vezes isso é bom. Veja como ler um arquivo texto em Java:
import java.io.*;
public class ReadingFromFile
{
public static void main(String[] args) throws Exception
{
FileReader fr =
new FileReader("arquivo.txt");
int i;
while ((i=fr.read()) != -1)
System.out.print((char) i);
}
}
Agora compare com a mesma coisa em Python:
print(open('arquivo.txt').read())
Nesse caso, parece óbvio que a resposta em Python é muito melhor, não? Agora olhe esse código em JavaScript:
Plugin de Acessibilidade para Twitter Bootstrap. Plugin de código aberto, no GitHub. Promete tornar acessíveis uma porção de componentes Javascript do Bootstrap e, até onde eu consegui conferir, funciona muito bem.
Considere incluir em seu próximo projeto. Considere incluir nos seus projetos antigos baseados em Bootstrap 3. Considere incluir sempre.
Apresentei hoje cedo uma palestra no GAiN, um encontro de profissionais de comunicação e internet da minha igreja. Há um tempo que venho falando às pessoas que trabalham com internet na igreja sobre os padrões do W3C. Mas hoje tive a oportunidade de falar para gente que trabalha com isso de toda a América do Sul, de uma vez.
Muito obrigado aos organizadores pelo convite. Quem quiser conferir minha palestra no GAiN, sobre as tendências para o futuro próximo da web, pode encontrar a apresentação aqui: aqui.
Não sei se minha palestra foi gravada. Se eles publicarem lá, aviso por aqui.
Alguém me perguntou há pouco o que eu acho do Sampa JS, por que eu não vou, por que eu não apoio o evento e etc. Resolvi responder por aqui, já que talvez mais alguém pode ter essa dúvida (se é que isso importa para alguém, né?)
Vamos lá, assunto pessoal: eu sou adventista do sétimo dia, por isso dedico o sábado a atividades não-profissionais: tempo com a família, trabalho voluntário de ajuda aos necessitados, estudo da Bíblia e oração. Por isso, não tenho ido a boa parte dos eventos de nossa área. A maioria acontece aos sábados. Em alguns outros, como o excelente Tableless Conf, eu simplesmente não consegui agenda para ir (ando trabalhando demais.)
Então, para quem estava curioso, é só isso.
Aliás, eu recomendo muitíssimo o Sampa JS, se você puder ir. Parece que vai ser um evento e tanto!
Detalhezinho sobre a linguagem que vale a pena conhecer, e uma boa dica de lógica sobre um erro muito cometido por iniciantes:
“We shouldn’t be fearful of writing about what we know. Even if you write from the most basic point of view, about something which has been ‘around for ages’, you’ll likely be saying something new to someone. That’s because there is no else if in JavaScript.”
SVG é suportado em tudo quanto é navegador hoje, incluindo o Internet Explorer 9. Isso significa que, num futuro próximo, você vai poder usar SVG sem medo. Enquanto isso, para boa parte das necessidades, você pode usar SVG com uma biblioteca de compatibilidade com IEs antigos, como a Raphaël e a svgweb.
Dá uma olhada nesse exemplo. Exibe o código fonte e você vai ver que isso aí foi feito com umas 300 linhas de javascript.
Qual o segredo?
SVG é um formato de XML para a descrição de gráficos vetoriais. O que significa que, diferente do que acontece com canvas, com SVG os objetos que você exibe na tela são de fato objetos, nós do DOM, na árvore do seu documento. Então dá uma olhada nesse outro exemplo. A animação do logo em cima e o gráfico interativo em baixo, tudo isso tem umas 35 linhas de Javascript apenas.
Então fica a dica: estude SVG. Tenho certeza que vai ser útil.
É impressionante a facilidade com que certas discussões técnicas ficam parecendo discussões sobre moral, ética ou futebol. Parece que é difícil entender o fato de que fazer uma escolha técnica diferente da sua não vai condenar ninguém ao inferno.
Veja, por exemplo, a questão da validação do W3C. Algumas páginas do site da Visie não passam na validação do W3C. E a gente não está nem aí para isso. Entenda bem, nós acreditamos na importância dos padrões web. A empresa se chama “Visie Padrões Web”. Mas acreditamos que padrões web são importantes porque tornam seu site acessível, compatível, rápido e indexável. Também são importantes porque formam um excelente conjunto de tecnologias para o desenvolvimento. Desenvolver direito com padrões web é a melhor relação custo X benefício.
Nada disso tem a ver com estar “certo”, politicamente correto, ou com conseguir ganhar um selinho. Tem a ver apenas com encontrar a melhor maneira de deixar meus usuários satisfeitos. Ponto.
O validador é uma ferramenta e tanto. Principalmente para quem está aprendendo HTML ou precisa corrigir um problema misterioso num site. Eu uso muito o validador em treinamentos. Mas ele não é um juiz, um crivo obrigatório sem o qual seu site não deveria nem ser publicado.
Javascript
Javascript é uma linguagem muito flexível, que permite muitas escolhas diferentes de modelagem, de técnica de codificação e até de estilo do código. E isso é um terreno muito fértil para os inventores de regras. Existem mil maneiras de preparar Neston. Nenhuma é mais “certa” do que a outra, o que define o que é certo são seus objetivos.
Não, não estou falando sobre a polêmica dos ponto-e-vírgula no código. Embora esse seja um assunto interessante, não é tão importante. Estou falando de algo mais.
Leia, por exemplo, o excelente artigo do Willian Bruno sobre orientação a objetos. Antes de criticá-lo, preciso dizer que o Willian usou uma abordagem muito didática, e escreveu código impecável. Vale a pena a leitura. A única coisa que eu recomendo ao leitor é que entenda que a abordagem usada não é a única correta.
Começando com o estilo de código para orientação a objetos. Tem gente que escreve construtores de objetos literais, como o Willian fez. Tem gente que escreve funções construtoras, para ser chamadas com new, e atribuem propriedades e valores dentro do construtor. Tem gente que escreve funções construtoras e atribui propriedades e métodos ao seu prototype. Há grandes diferenças de sintaxe e ligeiras diferenças nos resultados obtidos ao usar cada técnica. O ponto é: não escolha as regras de alguém como as suas sem entender primeiro os porquês.
Outro ponto tem mais a ver com a modelagem do que com estilo de código. O Willian usa um pattern bastante popular hoje em Javascript, o Module. E faz com ele controle de visibilidade, fazendo com que apenas um método seja visível fora do módulo. Esse estilo de modelagem, embora bastante popular, está longe de ser o único correto. Embora programadores Java e C sejam incentivados a se preocupar muito com isso, a maioria dos programadores Ruby usa com muita parcimônia o controle de visibilidade e a comunidade Python tem vivido muito bem sem esse recurso. Você pode escrever módulos com excelente nível de encapsulamento sem controle de visibilidade.
A mesma coisa se aplica a quase qualquer escolha em tecnologia. NoSQL não é a bala de prata que vai salvar a próxima geração de ERPs, mas vale a pena conhecer. Os novos recursos do HTML5 não vão tornar a jQuery desnecessária, mas você precisa conhecê-los. O Sublime Text não me fez largar o Vim, mas valeu muito a pena gastar um tempinho para ter uma segunda opção.
Moderação. Não é futebol. Não é religião. É só técnica.
Boa parte das APIs do HTML5 já estão disponíveis hoje para a maioria dos navegadores e, com um pouco de conhecimento e uma pitada de javascript, é possível desenvolver hoje aplicações com geoposicionamento, funcionamento offline, conexão em tempo real com o servidor, gráficos vetoriais e todo um novo conjunto de recursos de interface.
Por que esperar?
O HTML5 foi construído de maneira modular. Não é preciso esperar que toda a documentação esteja escrita para começar a trabalhar com ele. Você pode usar agora mesmo o que já está pronto.
Pensando nisso, preparamos este Workshop sobre as APIs do HTML5 e como construir a nova geração de aplicações web. Veja o programa.
Para iniciar este post, é preciso deixar algo claro: diferente da minha postura com os polêmicos ponto-e-vírgula, em que sei que sou “promíscuo e relaxado”, eu sou muito reticente quanto ao uso de eval() em javascript. O principal motivo é que eval() me cheira a gambiarra. Mas tenho muita dificuldade em dizer porquê. Na verdade, acho mesmo que é só uma questão de elegância.
Já li muita coisa sobre o assunto, mas nenhum argumento me convenceu. Os dois principais argumentos são performance e segurança. Em minha opinião nem um dos dois argumentos procede.
Performance
Em primeiro lugar, é preciso dizer que o argumento de que JSON tem pior performance raramente é verdade. Há alguns anos, código executado via eval não poderia ser cacheado ou pré-otimizado. Isso não é mais verdade hoje em dia. A V8 (Chrome), a Nitro (Safari) e a SpiderMonkey (Firefox) já trabalham com caching do código passado a eval em diversas circunstâncias. Além disso, pense nas situações em que eval seria útil. Não consigo imaginar uma em que performance seja um problema. Por exemplo, uso eval como um fallback para navegadores que não tem suporte nativo a JSON. Sinceramente, depois de um delay de dois segundos esperando por uma requisição Ajax, não faz absolutamente nenhuma diferença se interpretar esse retorno vai levar dez milissegundos a mais.
Alguém pode dizer que seria melhor nessa situação usar uma biblioteca JSON com validações, como a do Douglas Crockford. Mas isso acrescentaria 17Kb de código em troca de absolutamente nada. Alguém pode então argumentar que o que se ganha usando uma biblioteca dessas não é exatamente nada, mas pelo menos um validador do código antes da execução. Respondo a isso no final.
Segurança
O segundo argumento mais usado contra o uso de eval() é segurança. O fato de executar uma string, gerada dinamicamente, e não código escrito diretamente por você, pode dar calafrios. Puxa, mas não dá para ter a menor ideia do que será executado! Um agressor não poderia usar isso para executar código arbitrário? Isso não abre as portas para ataques XSS ou man-in-the-middle?
Aqui também, ninguém nunca conseguiu me demonstrar um único caso em que isso fosse uma preocupação real. Imagine o caso de uso que citei acima, por exemplo, de fazer parsing de dados JSON vindos via Ajax. Embora o código que vá passar por eval() não esteja no seu javascript, ele efetivamente foi escrito por você, no servidor. Se alguém consegue acesso a sua aplicação server afim de enviar dados maliciosos para suas requisições Ajax, por que ele se daria ao trabalho de fazer isso se ele poderia simplesmente gerar Javascript malicioso ou HTML malicioso? Se alguém teve esse nível de acesso a seu servidor, XSS é a menor de suas preocupações.
Outra variação do argumento da segurança diz que se você usa eval() a partir de uma entrada de dados do usuário, isso sim poderia abrir as portas para a execução de código malicioso. É preciso lembrar aqui que código javascript roda no client. Assim, o fato de eu poder digitar um script malicioso num campo de formulário, por exemplo, não significa nada exceto o fato de que posso “invadir minha própria máquina”.
Claro, se você recebe os dados gerados por esse eval() no servidor sem validá-los, isso pode causar problemas. Mas, nesse caso, o problema não está no eval() mas em sua validação porca no servidor. Se não houvesse eval() no código, a mesma coisa poderia ser feita na Firebug ou no console do Chrome.
Há ainda a preocupação com buscar dados de um servidor externo e executá-los, o que faria com que seu site possa executar código malicioso. Bom, se você inclui javascript em sua página gerado pelo Google Analytics, e pelo Twitter, Facebook, AddThis e outros geradores de widgets, porque não confiaria em executar código dessas mesmas fontes via eval()? Qual é exatamente a diferença?
Em suma, se as fontes de dados para o eval() não são confiáveis, não use-as de jeito nenhum. O problema não está no eval().
Qualidade de código
Um último argumento, menos usado mas em minha opinião mais relevante, tem a ver com a qualidade de código. O principal motivo que me faz evitar o uso de eval() é o fato de, se houver algum erro no código avaliado, será bem mais difícil debugar. O navegador vai acusar o número da linha do eval(). Esse é um forte argumento, mas não para todas as situações. Geralmente eu gero JSON no servidor com uma biblioteca ou módulo bastante confiáveis, tanto em PHP quanto em Python. Quais são sinceramente as chances de meu software falhar porque há um problema na biblioteca padrão de JSON do PHP?
Por isso, eu não costumo trocar um simples eval() pelo uso de uma biblioteca de JSON, por exemplo.
Fazendo errado
Não importa quão útil e boa seja uma ferramenta, sempre há uma infinidade de maneiras erradas de usá-la. Vi esses dias código assim:
eval('document.'+obj).className='selected'
Esse código é muito ruim, demonstrando um desconhecimento básico dos recursos da linguagem. Pode facilmente ser substituído por isso:
document[obj].className='selected'
Entenda que este artigo questionando os argumentos comuns contra o uso de eval() não é uma defesa de seu uso, principalmente de seu uso indiscrimado.
Seu argumento
Perdi alguma coisa? Há algo mais que precise ser dito? Por favor, fique à vontade para deixar seus comentários.
O que vai acontecer com seu site WordPress se ele receber muitas visitas? Aprenda neste Workshop as técnicas e segredos para manter seu site no ar, mesmo sob intenso tráfego.
Site bom é site rápido
A Amazon fez um trabalho de redução do tempo de carregamento em suas páginas e descobriu que cada décimo de segundo que suas páginas demoram a carregar representa 1% a menos de vendas. Ninguém gosta de sites que demoram a carregar.
Pensando nisso, preparamos este Workshop sobre otimização de performance em websites, focado especialmente em sites WordPress. Veja o programa
Novo local
Redesenhamos os Workshops da Visie. Serão eventos de menor porte, num lugar mais adequado a cursos de tecnologia, e também mais baratos. E esperamos que sejam mais frequentes. O lugar escolhido foi o MyJobSpace, que merece um post a parte.
E o primeiro Workshop que faremos neste novo formato é sobre um tema que acho apaixonante: performance. O Workshop Alta Performance com WordPress vai mostrar a você tudo o que você pode fazer, no servidor, PHP, em seu tema, plugins, HTML, Javascript, CSS e imagens para ter um site muito rápido.
Como temos apenas 34 vagas, é bom você não vacilar. Inscreva-se.
Acesse o HTML5 Please. Clique em use e dê uma olhada na lista. Agora clique em use with caution e confira a lista. Viu quanta coisa?
Por que a maioria dos exemplos de site em HTML5 brasileiros, dois anos depois de começarmos a usar esse treco, ainda são um mark-up levemente vitaminado e canvas?
Onde estão nossas aplicações offline? Web sockets? Drag-and-drop? Geolocation? Micro-data? Device orientation? Novos campos de formulário? SVG? History API?
Mas não tem demanda…
Você pode se desculpar por estar usando os mesmos velhos recursos de sempre, dizendo que os clientes da agência ou produtora onde você trabalha não querem os recursos novos, que seu chefe não quer saber dessas coisas, que tem trabalho pra caramba pra simplesmente recortar os layouts que recebe e não quer arrumar sarna pra se coçar…
Você vai mesmo querer passar o resto da vida recortando layouts? O mundo vai mudar, e você vai ser extinto, dinossauro. Se não tem demanda, crie a demanda. Comece a desenvolver projetos pessoais com o que você acha que seus clientes deveriam estar usando. Em seguida, mostre para todo mundo. Você vai ver se a demanda não aparece.
Todo mundo tem celular conectado. Todos os navegadores (até o IE) estão se esforçando para funcionar direito. É um momento mágico. É uma oportunidade que você não quer deixar passar. Um pouquinho de esforço aí, galera.
Durante esta semana estive no escritório do W3C Brasil, ministrando um treinamento de HTML5. Para encerrar o treinamento, o W3C organizou uma edição do Café com Browser.
Nós e o pessoal da Agência Click vamos mostrar um pouco do que já estamos fazendo com HTML5, e você pode assistir ao streaming ao vivo, cujo link será disponibilizado na hora.
O jogo é simples, e o objetivo é apenas apagar todas as luzes. Por curiosidade, fiz também o algoritmo que resolve o jogo:
O desafio está lançado. O primeiro que colocar nos comentários a URL de uma página com um botão “solve” como o meu ganha uma entrada para o Codeshow. Importante:
Vale o primeiro comentário. Mesmo que você comente de madrugada e eu demore a moderar, ganha quem comentar primeiro.
O solucionador tem que ser escrito em Javascript. Você pode copiar minha versão do jogo e desenvolver em cima dela.
Não pode resolver na base da tentativa e erro. Tem que ser uma boa solução, que resolva qualquer estado do tabuleiro em 20 passos ou menos.
Divirtam-se!
(O pessoal da Visie, se quiser participar, pode. Só não vai ganhar nada ;-))
Tem duas coisas que me incomodam nessa abordagem. A primeira é essa mania que muita gente tem, particularmente programadores PHP, de tratar UTF-8 como um “código alienígena” e ISO-8859-1 como normal e padrão. Alô, ISO-8859-1 é usado por parte do mundo. Não dá para escrever hebraico, mandarim, japonês, árabe ou russo com isso. ISO-8859-1 é uma das diversas tabelas de caracteres que existem mundo afora. E Unicode é a única maneira sensata de escrever um sistema que possa ser usado aqui e na China.
A segunda coisa que me incomoda é a quantidade de código. Não testei profundamente, mas tenho a impressão de que o código abaixo resolve o problema:
function utf8_decode(t){
return decodeURIComponent(escape(t))
}
Discussões sobre o melhor sistema operacional, o melhor navegador ou a melhor linguagem de programação tendem a entrar em loop infinito. Cada um dos lados parece achar o outro um completo idiota por não se convencer de suas opiniões.
Semana passada troquei algumas mensagens com o René de Paula que me fizeram pensar bastante sobre o assunto. O René provavelmente não me conhece, mas eu tenho aprendido muito com ele nos últimos anos, principalmente em seu podcast, o Roda e Avisa. E esse post não é um desabafo “estou chateadinho”. Estou citando o nome do René porque a conversa se deu no Twitter, ou seja, em público, e realmente me fez pensar.
O René recomendou esse artigo da ZDNet, analisando um estudo de segurança dos navegadores web. O artigo começa apresentando os resultados do estudo, em que o Internet Explorer ganha de lavada, e segue explicando porque, na opinião do autor, o estudo patrocinado pela Microsoft é tendencioso e irrelevante.
Respondi ao René dizendo que concordava com o artigo que ele havia indicado, que realmente o estudo era tendencioso. E usei a frase “o rei está nu.” Para mim, a crônica da roupa nova do rei é uma excelente metáfora para a situação. Ele me respondeu que havia visto meu blog e que achava que havia um “viés oculto” em tudo o que eu dizia. Em seguida twittou sobre o fato de as pessoas tratarem essas discussões como se fossem sobre times de futebol. Isso me fez pensar um bocado.
Eu gosto de, numa discussão, ouvir o outro lado. Também gosto muito de lógica. Se tem uma coisa que eu vou defender numa discussão, mais do que meu time de futebol, é o bom uso da lógica. Tento nunca ser irrazoável. Sei que todos somos tendenciosos, mas sempre tento ser mais imparcial que a média.
Talvez seja o fato de a discussão ter acontecido no Twitter, meio pouco propício, mas confesso que fiquei muito preocupado com a impressão que o René teve. Quem me conhece, sabe, trabalho com Linux, Windows ou Mac, sem rabo preso, escolhendo sempre o jeito mais simples de resolver cada problema.
Cada cabeça, uma sentença
Em primeiro lugar, não há um sistema operacional “melhor” e outro “pior”. Há um “melhor para você”. O fato de aquele seu amigo usuário de Windows não ter enxergado ainda que o Linux é o melhor sistema operacional do mundo talvez seja porque, para o perfil de uso dele, o Windows seja realmente o melhor sistema operacional.
Dificilmente eu tento convencer alguém a usar exclusivamente Linux. Sempre tento convencer as pessoas a experimentar. Se o sujeito me diz que é um heavy gamer, por exemplo, recomendo o uso de Windows. Sei, o Wine está muito evoluído e tal, mas se ele tem dinheiro para pagar as licenças e pode rodar a versão mais nova de cada jogo no ambiente em que ele foi feito para rodar, por que complicar?
Sim, não me esqueci, para certos perfis de uso, Mac OS X também é um sistema fantástico. Estou quase comprando um para minha mulher.
Existem, porém, padrões absolutos
O fato de não existir uma solução “bala de prata” e a paixão que costuma cercar essas discussões têm levado muita gente, principalmente programadores, a uma posição morna tão irrazoável quanto os extremos. É comum ouvir frases como “a melhor linguagem é aquele com a qual você sabe trabalhar” ou “a melhor ferramenta é a que resolve seu problema.”
Acredito sim que há casos de uso os mais variados. Mas, dentro de determinado caso de uso, há métricas objetivas que você pode usar para dizer o que é melhor. Falando em linguagem de programação, por exemplo, a melhor não é aquela que faz você se “sentir bem”. A não ser que programar para você seja só um hobby, a melhor é aquela que vai te permitir resolver mais rápido o problema do cliente, com a qualidade e a performance necessárias.
Dado um determinado problema do cliente, e uma determinada métrica de performance, deve ser possível apontar a melhor linguagem para essa situação.
Que problema seu software se propõe a resolver?
Se você é desenvolvedor de software, é importante entender isso. Você dificilmente vai encontrar uma oportunidade de desenvolver um produto que é o melhor para todo mundo. Não há unanimidades.
Você pode desenvolver algo que é o melhor para a maioria, pode achar uma minoria endinheirada, ou pode desenvolver algo legal para você mesmo e torcer para que haja gente parecido com você lá fora.
Mas, se você tentar ouvir todas as sugestões que receber e superar os concorrentes em absolutamente todos os perfis de uso, nunca vai terminar de desenvolver.
Mente aberta
Na Visie hoje temos 7 máquinas Windows, 6 Linux e 3 Macs. Sem contar as VMs, o ambiente de testes, e os servidores onde estão hospedadas as aplicações. Desenvolvedor, abra sua mente. Aprenda uma linguagem de programação nova, experimente outro sistema operacional, teste outra solução. Você vai aprender muito.
Aprenda Python, Ruby, Haskell ou Scala. Isso vai tornar você um melhor programador PHP, Java ou .Net. Desenvolva um projeto com uma banco de dados não relacional (estou usando MongoDB em um projeto.) Se você ama WordPress, faça alguma coisa com Joomla, e vice-versa. Tente outro framework, outro editor, outro jeito.
Sobre navegadores
No dia seguinte a essa conversa estive no escritório do W3C Brasil, assistindo ao Café com Browser com o pessoal do Internet Explorer.
Eles passaram boa parte do tempo falando sobre os recursos do navegador para o usuário final. Coisas como abas (oh!) e favoritos mais legais, webclips, processos independentes em cada aba, melhorias de performance e segurança. Tudo muito interessante mas, eu acho, apresentado para o público errado. Estávamos dentro do W3C, afinal de contas. Queríamos saber sobre as melhorias para o desenvolvedor.
Ao final, a palestra sobre melhorias para o desenvolvedor foi, para mim, parte surpreendente, parte decepcionante. Me surpreendi principalmente pela reação dos desenvolvedores no Twitter. Muita gente não conhecia as developer tools do IE8, ou os modos de compatibilidade, por exemplo. Quando foi apresentado o querySelector, muita gente twittou revoltada, porque a Microsoft estava “inventando um novo jeito proprietário de fazer as coisas”. Gente, o querySelector é uma recomendação do W3C (está em Working Draft, mas está lá.)
A parte decepcionante, expressei em minha pergunta:
Em suma, não tenho ódio da Microsoft ou de quem quer que seja. Não quero que o Internet Explorer suma do mapa. Ainda tenho projetos em ASP, VB e .Net, e sou feliz com isso. Só quero poder desenvolver uma vez só minhas aplicações. Quero não ter que cobrar do cliente pelo custo de fazê-la funcionar no Internet Explorer. Quero entregar mais rápido aplicações melhores, mais estáveis, com menos código.
Um amigo me escreveu agora para mostrar algo muito curioso. Abra sua Firebug, ou qualquer outro lugar onde você roda Javascript, e teste:
new Date(2008,8,11)
Você deve ter como retorno um objeto de data, que se impresso mostra:
Thu Sep 11 2008 00:00:00 GMT-0300 (BRT)
Porque setembro e não agosto, você pode se perguntar. É porque em Javascript, assim com na maioria das linguagens de programação, arrays começam com zero, então faz sentido que contadores também comecem com zero. Assim, janeiro é o mês zero, e se você precisar construir um array com os nomes dos meses, janeiro será o primeiro do array. Faz todo o sentido.
Agora, o que não faz sentido. Tente:
new Date(2008,9,12)
Aqui no meu sistema eu obtive:
Sat Oct 11 2008 23:00:00 GMT-0300 (BRT)
Ou seja, uma hora mais cedo. O que será isso? Correção para o horário de verão? Se é, em que regra se baseia? Os horários de verão no Brasil mudam todo ano, e dependem de em que estado você está.
Mas você que é de São Paulo, tem a oportunidade de ver tudo funcionando ao vivo. Nessa quinta-feira, na palestra “Formulários Definitivos“, vou construir um validador igualzinho a esse do zero, explicando cada conceito e o porquê de cada decisão no projeto.