Matemática para jogos – Parte 2 – A física da colisão

Continuando a série sobre desenvolvimento de jogos, após verificar a colisão, o próximo passo é entender o que acontece no mundo real durante uma colisão. Como praticamente todos os simuladores de colisão que achei são feitos em java e tem um applet nojento na página, para poder escrever esse post eu criei um simulador de colisão em html usando canvas e javascript, o jscolisao que também tem código aberto.

Disclaimer: Não sou físico e posso escrever alguma besteira aqui, então não use esse material para escola, faculdade e afins, mas use à vontade para seus jogos.

Colisão é um estudo sobre troca de energia e movimento, portanto, quando dizemos que houve uma colisão estamos dizendo que houve uma troca de energia e movimento entre os corpos envolvidos.Voltando ao exemplo do meu jogo, sempre que a bolinha se choca com algum jogador ou parede temos que simular essa troca de velocidade. Neste post vou comentar apenas sobre a colisão na parede, que é mais simples.

Antes de começar a usar o simulador vamos lembrar um detalhe importante sobre colisões, o tipo de colisão. Existem aquelas colisões onde não existe perda de energia e toda a energia do momento da colisão é mantido, como no famoso Pêndulo de Newton, que num mundo ideal funcionaria eternamente, esse tipo de colisão é chamado colisão elástica. O fator fundamental para esse tipo de colisão é o chamado coeficiente de restituição. Imagine a colisão entre o seu pé e uma bola de futebol, no momento que você a chuta ela visivelmente se deforma, acumulando energia, e depois ela volta à forma original de bola, liberando esta energia. Independente de quão visível é a deformação, a energia sempre é transmitida e cada material tem o seu proprio coeficiente de restituição, que nada mais é do que a quantidade de energia que ele consegue propagar. Para descobrir o coeficiente de restituição de um elemento, basta pegar a soma das velocidades após a colisão e dividir pela soma das velocidades no instante da colisão, ou seja, caso não haja perda de velocidade, os números serão iguais antes e depois, resultando num coeficiente de restituição igual a 1.
Para as colisões que o coeficiente de restituição são menores do que 1, significa que houve perda de energia, e pode resultar numa colisão parcialmente elástica, que seria igual a anterior, mas com perda de energia ou uma colisão perfeitamente inelástica, que é quando os corpos se juntam durante a colisão e seguem como um único corpo com a soma das massas após a colisão.
Só por curiosidade, caso o coeficiente seja maior que 1, significa que houve um ganho de energia durante a colisão, o que até onde eu saiba não existe, mas foi retratado no filme infantil Flubber, e pode ser testado no simulador sem problemas.

Além do coeficiente de restituição os outros dados importantes para serem analisados durante a colisão são a massa e a velocidade dos corpos no instante da colisão. Com esses dados na mão basta usar a seguinte fórmula: v1f = (1+e)m2v2i/(m1 + m2) + v1i(m1 – m2 e)/(m1 + m2) onde:
e = coeficiente e restituição
m1 = massa do corpo 1
m2 = massa do corpo 2
v1i = velocidade do corpo 1 no momento da colisão
v2i = velocidade do corpo 2 no momento da colisão
* Como não quero que essa série passe de 3 ou 4 posts, eu vou deixar os detalhes por trás da fórmula da colisão nesse excelente material que encontrei.

Neste instante o foco é na colisão da bolinha com as paredes, então vamos rever esta fórmula. Como estamos trabalhando num mundo ideal vou considerar que o coeficiente de restituição é 1. Além disso, reparem que a primeira parte da fórmula é (1+e)m2v2i/(m1 + m2). Como a velocidade da parede é zero e qualquer coisa multiplicado por zero vai resultar em zero, e zero divido por qualquer coisa também vai ser zero, sempre que o segundo corpo não estiver em movimento antes da colisão, essa primeira parte da fórmula vai ser sempre zero. O que sobra pra nos preocuparmos então é v1i(m1 – m2 e)/(m1 + m2). Mas agora vem um problema, quanto pesa a bolinha? E a parede? Vamos fazer uma simulação simples, imagine que a massa da bolinha é 1 e da parede é 1000. Lembrando que estamos trabalhando com e=1, então vamos ter:
v1f = v1i(1 – 1000 *1) / (1 + 1000) -> v1f = v1i * -999/1001.
Agora vamos imaginar que a bolinha pesa 0.1 e a parede pesa 1000000. Teremos:
v1f = v1i(0.1 – 1000000 *1) / (0.1 + 1000000) -> v1f = v1i * -999999.9/1000000.1.
Na primeira simulação teríamos vf = vi * -999/1001 -> vf = vi * -0.998001998. E na segunda simulação teríamos vf = vi * -0.9999998.
Reparem que quanto maior a diferença entre as massas mais próximo de -1 será este último termo. Logo, quando a massa do corpo 1 é desconsiderável comparada a do corpo 2 teremos que vf = vi * -e. Como estamos trabalhando com e = 1, teremos uma velocidade final que será igual a velocidade do instante da colisão multiplicado por -1. Lembrando que no jogo, eu sempre guardo a velocidade em 2 variáveis diferentes, 1 para o eixo x e uma para o eixo y. Quando bato nas paredes verticais, eu mantenho a velocidade vertical e multiplico a horizontal por -1, e nas paredes horizontais o oposto.

Acho que muita gente que já brincou com este tipo de problema sempre fez a multiplicação por -1, mas poucos realmente entendiam o porquê. Espero que este post tenha esclarecido este outro mistério e não deixem de conferir o material que citei acima, e aguardem o próximo post onde vou resolver o problema da colisão com os jogadores.

Posted in Jogos, Matemática

Matemática para jogos – Parte 1 – Colisão de círculos

Por uma incrível coincidência, assim como alguns dos meus amigos ex-caelum, recentemente voltei a estudar sobre o desenvolvimento de jogos. Há algumas semanas fiz um quase jogo para aprender um pouco sobre o canvas do HTML5 e WebSockets. O código está no meu github.

Óbvio que desenvolver jogos tem os seus desafios de programação, mas o que mais me surpreendeu na minha experiência foi como um jogo tão estupidamente simples me exigiu tamanho conhecimento sobre física e matemática, então nessa primeira série de posts sobre desenvolvimento de jogos, decidi focar nesta parte do problema.

O jogo em questão é alguma coisa parecida com um “Air Hockey” onde existem 2 jogadores representados por 1 disco grande cada, e um puck (bolinha) representado por um disco menor. O jogo todo é desenhado em um canvas 2D, então cada um dos 3 elementos é representado por 3 números: um raio e uma coordenada (X, Y).
Durante o game loop tenho que verificar se o puck colidiu com alguma parede ou jogador para mudar a sua rota, e aí vem o primeiro problema que vou abordar aqui. Para verificar se o puck colidiu com algum jogador temos que verificar a distância entre os 2 pontos, como na imagem abaixo.

Imagem 1

Imagem 1

Existe uma formula “mágica” para calcular a distância entre pontos, mas como não sou muito fã de coisas obscuras, aqui vai uma explicação detalhada do problema. Se imaginarmos um retângulo com os pontos como vértices opostos, vamos ver que se traçarmos a linha que une esses pontos, temos 2 triângulos retângulos e que a distância entre os pontos nada mais é do que a hipotenusa deles.

Imagem 2

Imagem 2

Considerando que os pontos são A(20, 30) e B(50, 40) conseguimos descobrir o tamanho do nosso retângulo com um lado igual a Bx – Ax (50 – 20 =>; 30) e outro com By – Ay (40 – 30 =>; 10). Temos um retângulo de 30 por 10.

Imagem 3

Imagem 3

Agora basta considerar o triângulo com lados 10, 30 e X, onde X é a hipotenusa deste triângulo retângulo e finalmente a distância entre nossos pontos. Para quem não lembra, a hipotenusa é calculada com a famosa fórmula “Raiz da soma dos catetos ao quadrado” =>; √(10² + 30²) =>; √(1000) =>; 31.6227766017.

Para finalizar faltou considerar o tamanho dos círculos inteiros e não somente seus pontos centrais, então para saber se ocorreu a colisão basta verificar se a soma dos raios é maior ou igual a distância entre os pontos.

Image 4

Image 4

Considerando que tenho um objeto “bola” e um “jogador”, a fórmula final para saber se teve colisão seria algo como

distancia = sqrt((jogador.x - bola.x)^2 + (jogador.y - bola.y)^2)
bola.raio + jogador.raio >= distancia

PS: As imagens não estão com a proporção correta, fiz tudo a mão livre apenas para ilustrar.
PPS: Simplifiquei a questão do módulo entre os pontos para formar o retângulo porque não são relavantes no resultado final, dado que sempre vamos usar o quadrado do número e, neste caso, sempre vai resultar em valor positivo.

Posted in Jogos, Matemática

[Dica Rápida] Bulk update (atualização em massa) no Rails

Depois de muito tempo sem postar nenhuma dica rápida, estou escrevendo uma de Rails agora.
É relativamente comum precisarmos fazer uma atualização em mais de uma linha da mesma tabela e quando se está usando o ActiverRecord é muito comum pensar em fazer um where e depois, usando um update_attribute, atualizar os registros. Algo como:

Usuario.where('login in (?)', ['a', 'b', 'c']).each do|u|
 u.update_attribute :status, :bloqueado
end

O grande problema desse código é que ele irá executar 4 comandos SQL diferentes, mas seria fácilmente resolvido com apenas 1. Para que o ActiverRecord execute um único comando update com a cláusula where basta usar o método update_all:

Usuario.where('login in (?)', ['a', 'b', 'c']).update_all( status: :bloqueado )

Dica rápida parte 2: Além do update_all também existe o delete_all.

Tagged with: , , ,
Posted in dica rapida

Da IDE ao editor de texto, do editor de volta a IDE e de volta de novo ao editor

Infelizmente estou escrevendo bem menos do que gostaria, especialmente nestes últimos meses que nem se quer passei aqui no blog e praticamente não usei nem o twitter. Estou preparando um post offtopic onde vou comentar melhor sobre tudo o que passei nestes últimos meses e o que estou preparando para os próximos, mas pra “tirar a poeira” daqui vou comentar um pouco sobre meu ambiente de novo.
No final de 2010 escrevi sobre meu ambiente de desenvolvimento e naquele momento finalmente estava me adaptando de vez ao vim e largando completamente o TextMate. O “grande problema” é qua meses depois disso acabei trabalhando num projeto scala na Caelum e o ambiente que o pessoal que iniciou o projeto estava usando era o IntelliJ IDEA. Como eu não sabia nada nem de scala nem do projeto, entrei na onda do pessoal e instalei a IDE. Até aí nada de mais, porem eu ainda trabalhava com java e ruby e o IntelliJ IDEA é uma IDE fantástica com suporte para todas essas e muitas outra linguagens com plugins muito mais maduros e estáveis do que os para eclipse, então resolvi dar uma chance e tentar concentrar tudo nesta IDE. Apenas 1 set de atalhos independente da linguagem e projeto sempre foi um sonho pra mim que vivia fazendo shift de ambiente dependendo do projeto, então por que não tentar? Tentei, e por incrível que pareça passei muito perto de conseguir, mas uma pequeno detalhe me incomodava muito… o preço. Pra quem não sabe eu sou radical contra a pirataria (de software) e embora o IntelliJ seja muito bom, não foi bom o bastate pra me convencer a pagar U$199,00 por ele. Uma alternativa seria usar a versão gratuita que da suporte a java e scala e comprar apenas o RubyMine que é o equivalente ao plugin de ruby do intelliJ mas em versão standalone, o que baixaria o preço da licença para apenas U$ 69,00. Sem dúvidas valeria mais a pena do que comprar o TextMate, mas fui tentar outras alternativas antes de gastar dinheiro com outra ferramenta que, assim como o meu TextMate, um dia poderia se revelar um grande desperdício.
Resolvi então voltar as origens de quando estava aprendendo ruby, dado que estava querendo um ambiente completo e unificado nada melhor do que dar uma chance a minha IDE java que mais usei, o eclipse. Instalei o famoso RadRails e comecei a trabalhar com ele, trabalhei nuns exemplos de java 7, desenvolvi meus projetos ruby do dia-a-dia, dei uma olhada num projeto python que precisei e embora as coisas estivessem mais ou menos boas os constantes erros bizarros e eventuais crashs me incomodam muito. Eu sei que parte disso é porque sempre uso as versões beta do eclipse, mas num dos updates que aconteceram eu simplesmente “crashei” meu workspace e perdi todas as customizações que costumo fazer. Mesmo assim reconfigurei o eclipse inteiro, mas com menos plugins, apenas o Eclim e o já citado Aptana RadRails. Mesmo com um ambiente relativamente enxuto comparado ao monstro que meu eclipse costumava ser, ele continuou se mostrando um ambiente bom o bastante para conseguir trabalhar, mas não pra me deixar completamente satisfeito, sem contar que consumo de memória começou a me incomodar. Estou começando a estudar sobre desenvolvimento de jogos e as ferramentas são bem pesadas e mesmo com meus 8GB de RAM não estava conseguindo “brincar um pouco” sem ter que fechar minhas coisas de trabalho, logo tomei a mesma decisão que tinha tomado em 2010 e desisti do ambiente único integrado e usar a melhor ferramenta para cada atividade. Provavelmente nunca vou programar java num editor de texto então porque querer tanto usar uma IDE pra programar ruby?
Observação importante: O IntelliJ/RubyMine consegue sim te dar boas sugestões no autocomplete e na maior parte das vezes ele acerta perfeitamente a implementação dos métodos no “control click”, inclusive para métodos declarados em gems, métodos sobrescritos e etc, mas tem seu preço. O Aptana ainda está muito longe disso!!

Já que era pra usar um editor de texto de novo e não estava nem se quer considerando o TextMate, poderia testar o Sublime, testar o Emacs ou simplesmente voltar a usar o VIM.
Por pura preguiça e falta de tempo tomei a decisão mais fácil e fui direto ao VIM, mas para não passar raiva de novo ao invés de simplesmente pegar o bundle de alguém desta vez fiz a coisa com um pouco mais de carinho e fui entender e aprender a usar os plugins que eram importantes para mim. Cheguei a conclusão que as funcionalidades que não consigo viver sem são:

  • Busca no projeto. Muitas vezes queremos fazer uma busca não apenas no arquivo aberto, mas em todos os arquivos do projeto e me irritava ter que abrir outra aba/split para fazer um grep e depois ter que ficar olhando um por um. Pra este problema temos o Ack
  • Árvore de diretórios. Funcionalidade que faz parte de quem está acostumado com ides, mas não são essencial aos editores de texto. No vim basta colocar o NERDTree. Como tenho o hábito de usar tabs ao invés de splits coloquei também o NERDTreeTabs que melhora a usabilidade
  • Abrir arquivos pelo nome com busca inteligente. Quando você já sabe o nome do arquivo, ou pelo menos parte dele e quer apenas digitar esse nome e abrir o arquivo. Estou usando o Command-T
  • Toggle de comentário. Parece um funcionalidade idiota, mas me irrita muito ter que editar várias linhas para comentar um bloco. NERDCommenter é a melhor ferramenta que existe pra isso. ’5,ci’ vai comentar 5 linhas e pronto, não precisa nem marcar antes nem nada.
  • Feedback rápido para erros. Sabe quando você faz aquele método bizarro, salva o arquivo, vai pro browser, atualiza e “pã!”. Vai olhar a stacktrace e foi porque você trocou 2 letras na digitação ou esqueceu o ‘;’ ou qualquer outro erro idiota desses? Syntastic mostra um erro claro assim que você salva o arquivo. Algo parecido com um erro de compilação mesmo para linguagens dinâmicas como Ruby

Além desses ainda tem os não tão importantes mas que ajudam muito durante o dia como o Endwise, Rails, vim-ruby e alguns outros. Acabei pegando o bundle do scrooloose como base que tem praticamente todos esses que decidi que precisava e mais alguns outros desses utilitários e ainda assim é um bundle bem enxuto. Acabei criando meu fork e fazendo algumas poucas configurações extras basicamente por causa do meu hábito de usar abas.

Posted in Uncategorized

Renomeando arquivos em ruby

Primeiro post do ano ressuscitando a categoria dica rápida.
Há uma ou duas semanas o PotHix me passou umas músicas, mas na hora de copiar, todos os arquivos vieram sem extensão. Depois de perder um tempo tentando resolver com bash, eu desisti e resolvi o problema em 10 min usando ruby. Se alguém puder postar nos comentários a solução em bash eu agradeço!

Para a minha solução usei apenas os seguintes métodos:

#Retorna um array de strings com todos os arquivos do diretório.
Dir.entries("dir")
#Retorna se o arquivo é um diretório ou não.
File.directory?("arquivo")
#Renomeia o arquivo.
File.rename("nome_antigo", "nome_novo")

Minha solução final ficou assim:

def rename_in_dir(dir)
  files = Dir.entries(dir)
  files.each do |f|
    # Usei esse if para ignorar os arquivos que já tinham
    # extensão e as referências '.' e '..'
    next if f == "." or f == ".." or f =~ /.*..{2,4}$/

    # é importante sempre usar o diretório junto, se não ele vai
    # procurar sempre no diretório onde o script está sendo executado
    if File.directory?("#{dir}/#{f}")
      # Se for um diretório faz a chamada recursiva
      puts "DIR: #{dir}/#{f}"
      rename_in_dir("#{dir}/#{f}")
    else
      puts "renaming: #{dir}/#{f}"
      # Adiciona a extensão .mp3 no arquivo
      File.rename("#{dir}/#{f}", "#{dir}/#{f}.mp3")
    end
  end
end

# Começa a partir do diretório onde o arquivo está
rename_in_dir(".")
Tagged with: , ,
Posted in dica rapida, Ruby

Minha opinião sobre ambiente de trabalho

Muito palpite e pouco estudo na nossa área acabam gerando grandes discussões sobre o ambiente de trabalho. Afinal, baias são ruins, mesões geram barulho e distrações, as pessoas precisam ter o seu espaço, e tantas outras questões sempre são levadas aos pobres tomadores de decisão sobre a montagem da área de trabalho dos funcionários.
Estou prestes a completar meu primeiro mês de Locaweb e tive vontade de escrever sobre assunto já que, embora tão parecido com a Caelum, minhas sensações são completamente diferentes, o que me fez refletir sobre o que realmente gosto e não gosto no assunto. Infelizmente esse post é apenas a opinião de mais um e nada além disso.

Eu adorava o ambiente que tinha na DClick e na Caelum e também estou gostando muito das coisas aqui na Locaweb, com regras apenas de bom senso: vista o que quiser, chegue na hora que quiser, apenas faça suas horas semanais e cumpra seus deveres não importa como. Na minha opinião isso deveria ser regra para área de desenvolvimento, mas na hora de comprar os móveis é que as dúvidas começam, então vou listar alguns itens que considero importantes e comentar sobre os prós e contras que vivi nesses últimos anos.

Mesas

Sempre fui defensor dos mesões. Sempre achei que o ganho em comunicação vale mais do que as eventuais distrações que podem gerar, porém tanto a DClick quanto a Caelum são empresas relativamente pequenas, em ambas a nossa “salona” tinha no máximo 20 devs. A experiência das mesonas aqui na Locaweb está sendo bem menos produtiva pra mim. Na minha primeira semana aqui tive dias de produtividade MUITO baixas que atribuí ao barulho na sala. Não sei qual seria o número máximo de pessoas, ou se o problema não é quantidade e sim o bom senso, mas a questão é que hoje preciso me controlar bem mais para render o que gostaria num dia de trabalho. Aqui, além das mesonas existe outro fator que talvez seja o real “vilão”, que são as brincadeiras. Na Caelum era comum ver uma pessoa ou outra brincando com os dardos ou fazendo malabares, mas aqui na Loca é comum ver pessoas fazendo “guerrinha” com suas NERFs. Embora seja óbvio que “guerrinha” seja uma distração muito grande, nas outras empresas também tínhamos momentos de “distração coletiva” ou simplesmente barulho intenso, por isso não tiro a “culpa” dos mesões para esse tipo de bagunça.
Veredito: Use com bom senso. Claro que é mais fácil “controlar” 20 do que 500, mas mesmo para times grandes acho que vale a pena a utilização dos mesões, mas é necessário um pouco mais de responsabilidade dos funcionários.

Lugares fixos

Uma das coisas que mais senti falta quando fui para a Caelum era de ter o MEU lugar. Sempre gostei de ter a minha bagunça, fotos, planta (na DClick eu tínha um cactus na mesa, aqui na Loca ainda não), enfim, personalizar o lugar como você preferir. Tanto na DClick quanto aqui na Loca tenho essa possibilidade, mas na época de Caelum não tínhamos, e embora sentisse falta disso, lá faz muito sentido ser da maneira que é. Mais importante do que trazer a foto da familia é sentar próximo do seu time de trabalho. Aqui na Loca os time são bem definidos e pelo o que entendi, existe uma baixa rotatividade de pessoas entre times, na Caelum é exatamente o oposto. Lá não existe uma separação muito clara entre os times e a rotatividade é MUITO grande. Não faz o menor sentido você customizar seu lugar se vai trocar de lugar toda semana. Um ponto curioso sobre o assunto é que na DClick era mais ou menos o meio do caminho. Existem (pelo menos existiam) times bem definidos por projeto, mas a rotatividade era média e fazer a mudança eventualmente valia a pena. Durante o ano que trabalhei lá me lembro de ter remanejado minhas coisas pelo menos umas 3 ou 4 vezes.
Veredito: Dê preferência por manter os times juntos e, se as mudanças não forem frequentes, vale a pena deixá-los fixos.

Cadeiras

Compre cadeiras boas para seus funcionários! Eu sei que não é barato, mas além de lei, faz toda a diferença chegar em casa após um dia de trabalho numa cadeirinha vagabunda ou numa cadeira que você pode configurar altura, encosto e etc.
Veredito: Não precisa ser cadeira de presidente, mas compre pelo menos uma de rodinha com regulagem de altura, encosto e braços.

Monitores

Desde que usei dois monitores pela primera vez na DClick me apaixonei pela experiência. Poder ver o código e browser ao mesmo tempo ajuda MUITO no dia-a-dia. Se for optante pelos lugares fixos, compre 2 monitores pra todo mundo! (vai sair mais barato do que a cadeira), se não, deixe alguns espalhados pelas mesas para que as pessoas usem. Uma observação importante sobre essa opção é: quanto mais difícil for de usar, menos eles serão usados, então tente deixar tudo prontinho para apenas espetar o computador e sair usando.
Veredito: Eu me sinto bem mais produtivo usando outro monitor. Acredito que vale o investimento.

Copa/Cozinha/Banheiro

Essa parte é bem mais difícil de gerenciar pois na maior parte dos casos não temos como colocar um banheiro a mais onde queremos, mas é um fator que não deveria ser completamente ignorado. Na DClick a copa era pra um lado e o banheiro pra o outro, mas ambos bem próximos da maioria. Na pior da hipóteses ou você sentaria bem perto de um e um pouco longe do outro. Na Caelum, na última configuração de sala que tínhamos quando saí de lá, a “copa” estava integrada à nossa sala o que era ótimo. O único problema que tivemos com isso foi a facilidade que as pessoas tinham em comer nas mesonas e acabava sujando um espaço coletivo. Bastou uma conversa e tudo se resolveu. Quanto aos banheiros lá, usavamos os da área comum do prédio. Relativamente próximos com a desvantagem de ter que levar uma chave com você, além de ser só um por andar (relativamente comum tentar ir ao banheiro e estar ocupado). Aqui na Loca, tanto o banheiro quanto a copa ficam nos cantos do prédio e em apenas 2 cantos. Pra piorar, o banheiro masculino é de um lado e o feminino é do outro, ou seja, dependendo de onde você se sente pode ser uma longa jornada até você se aliviar ou conseguir o seu café. Porém, se sentar perto do banheiro vai acabar vendo um grande fluxo de pessoas por perto. Embora veja isso como um desperdício (pra que já leu um pouco sobre lean sabe do que estou falando) não vejo uma solução plausível para esse caso.
Veredito: Definitivamente comportar 500 pessoas é BEM mais difícil do que 20, mas tente se preocupar com esses detalhes na hora de escolher o prédio. Sem dúvidas seus funcionários precisão ir ao banheiro e quanto menos tempo eles demorarem, melhor pra todos! Prefira os ambientes com banheiros e copas (café) acessíveis e de preferência que sejam iguais para todos, independente de onde sentam.

Esses são os principais fatores físicos que acredito afetar a minha produtividade durante o dia-a-dia. Em nenhuma das 3 empresas que citei no post tive 100% dos itens que mais gosto e fui/sou muito feliz como funcionário de todas, então não se preocupe se não conseguir todos, mas tente fornecer o máximo desses itens para seus funcionários.
Lembre-se do princípio ágil:
“Construa projetos em torno de indivíduos motivados.
Dê a eles o ambiente e o suporte necessário e confie neles para fazer o trabalho.”

Pra finalizar, fotos da minha mesa aqui na Locaweb:

Tagged with: , , ,
Posted in Agile

QConSP 2011

No final de semana passado aconteceu a segunda edição da QConSP e, novamente, tive a grande honra de ajudar na organização das Lightning talks (LT) no final do primeiro dia do evento como Host da track.

Mais um evento organizado pela Caelum, obviamente com seus altos e baixos, mas muito mais altos do que baixos.

Questões como espaço, horário e lanches foram praticamente perfeitos e grandes apresentações como as do Jim Webber, Rebecca Parsons e o muito simpático Khawaja Shams com seus robôs dançantes e seu knob (botão) que cria máquinas na Amazon foram momentos de destaque do evento. Infelizmente alguns palestrantes acabaram decepcionando um pouco, mas este é o tipo de problema que não temos como prever e sempre vão acontecer em qualquer evento do mundo.

Outra grande vantagem desse tipo de evento é poder rever alguns amigos e ex-colegas de trabalho e matar a saudade do pessoal, além de conhecer novas pessoas e em alguns casos conhecer fisicamente algum grande amigo de internet (Acreditem, isso acontece! E muito!).

Gostaria de agradecer todos que participaram da organização do evento, os hosts das tracks e o Luiz Bassi da Caelum, que foram as principais pessoas por trás deste grande evento. Além disso um agradecimento especial para todos que apresentaram LT comigo:
Christian Reichel, que apresentou “Por um Java mais funcional”, onde mostrou exemplos de funções como map e reduce em java usando o Guava;

Diego Chohfi, que agora também faz parte do time da Caelum, mostrou um pouco do dinamismo não muito comentado do Objective-C;

E 3 grandes colaboradores do VRaptor falando sobre algumas funcionalidades extras do framework:

Washington Botelho que mostrou como implementar um controle de permissões baseado em perfis;

Rodolfo Liviero, autor do Vraptor-scaffold, mostrou como criar e “deployar” uma aplicação VRaptor no heroku em menos de 5 min usando seu projeto;

Guilherme Silveira que comentou sobre os vários plugins já criados para o VRaptor e ainda deu um “puxão de orelha” no pessoal presente para que extraiam plugins e colaborem com o projeto.

A minha apresentação foi mais abstrata e basicamente questionei sobre a integração de sistemas usando frameworks MVC em vários pontos diferentes sobe o título “MVC além do MVC”. Slides:

Posted in Arquitetura, Palestras / Apresentações

Alguns projetos Open Source

Antes de mais nada, me desculpem pelos meses que o blog anda sem atualizações, um dos motivos é justamente o que vou comentar neste post. Desde o começo do ano passei a contribuir um pouco mais com projetos Open Source e neste post vou falar um pouco sobre 3 colaborações que gostei muito de ter participado e que o resultado final me agradou muito também.

VRaptor Flex Plugin

Em ordem cronológica o primeiro “grande” feito ao Open Source neste ano foi ter criado, com a ajuda do Lucas Cavalcanti e do Erich Egert um plugin para o VRaptor que possibilita as chamadas remotas usando o protocolo AMF. Na verdade não fizemos todo o trabalho de (de)serialização, mas assim como o suporte para Spring, EJB, etc.  O que fizemos foi criar uma factory que você deve registrar no framework que realmente sabe fazer a serialização para AMF. Por enquanto estamos suportanto o BlazeDS e o GraniteDS.

Para saber um pouco mais sobre o plugin e como configurar e usar veja o página no próprio github para issues podem usar a mesma página de issues do VRaptor.

Stella 2.0

Alguns de vocês já deve ter ouvido falar no Stella. Um projeto com um monte de utilidades para desenvolvedores brasileiros, como validadores de CPF e CNPJ, gerador de boleto, conversor de números por extenso e um pouco mais. Embora muito útil, o projeto andava meio parado e recentemente eu, o Mario Amaral e o Paulo Silveira, além de outras contribuições da comunidade, atualizamos o projeto para suportar as “novas” especificações do JEE6 como o JSF2 e Bean Validation, além de muita refatoração e algumas melhorias na API.

Acabamos de liberar um release beta e em breve devemos ter uma versão 2.0 final disponível.

Static Server

O último projeto que trabalhei recentemente surgiu no momento de subir o site do Stella. Na Caelum estamos numa tendência de cada vez mais tirar a responsabilidade de infra das nossas mãos, então mesmo com um site estático a gente queria subir no Heroku ou Google App Engine. Pensamos em criar uma aplicação rails e deixar todos os arquivos no public, mas não fazia o menor sentido, então comecei a fazer usando apenas Rack, mas ficamos com o problema da home, aí comecei uma dsl pra configurar forward e redirect, fui refatorando até que surgiu o StaticServer que já está no rubygems como static_server.

Em breve vou colocar uma documentação melhor, mas por enquanto vocês podem ver os exemplos nos testes de integração.

Ajude você também

Esses e tantos outros projetos, brasileiros ou não, sempre precisam de ajuda, seja com código, documentação, exemplos e até mesmo encontrando e registrando bugs. Toda ajuda é bem vinda, sempre!

Em breve devo colocar mais exemplos e possivelmente escrever posts com mais detalhes da utilização de cada um deles.

Tagged with: , , , , , , , ,
Posted in Flex, Java, Ruby

Melhorando os testes dos seus models do Rails 3 com RSpec 2 e Remarkable ou Shoulda

Uma das coisas que mais me incomoda quando estou fazendo os meus testes,  é escrever testes para verificar os campos obrigatórios. Eu gosto muito de usar o RSpec e aqui está um exemplo comum de código que testa um modelo ‘Usuario’ que tem os atributos ‘nome’ e ‘idade’ obrigatórios:

describe Usuario do
  before :all do
    @obrigatorios = {nome: 'David Paniz', idade: 25}
  end

  it "deve ter Nome obrigatório" do
    u = Usuario.new(@obrigatorios.merge(nome: nil))
    u.should_not be_valid
    u.should have_at_least(1).error_on(:nome)
  end

  it "deve ter Idade obrigatório" do
    u = Usuario.new(@obrigatorios.merge(idade: nil))
    u.should_not be_valid
    u.should have_at_least(1).error_on(:idade)
  end

  it "Deve ser valido com todos os campos obrigatório" do
    u = Usuario.new(@obrigatorios)
    u.should be_valid
  end
end

Sempre que escrevo um código desses sinto que estou testando o Rails e não o meu model. No fundo a única coisa que tenho que testar é se eu coloquei a linha do validates_presence_of :atributo. O resto do trabalho (deixar o valid? falso e criar o error no campo) é problema do Rails e não do meu modelo. Além desse sensação estranha de testar a coisa errada esse é o tipo de código que eu escrevo e na hora percebo que a abordagem não é nada DRY.

Dei uma olhada em 2 opções para melhorar a abordagem dos testes, o Shoulda e o Remarkable.

Remarkable

Para instalar o remarkable com o Rails 3 o RSpec 2 precisamos usar a versão 4 que ainda está em alpha, nesse instante 4.0.0.alpha4.
Adicione ao seu Gemfile as dependências:

gem "rspec"
gem "rspec-rails"
gem "remarkable_activerecord", '4.0.0.alpha4'

Usando o Remakable você ganha alguns matcher especiais para verificar apenas se você realmente colocou a validação do atributo no seu model, por exemplo o matcher validate_presence_of. O código de teste equivalente ao de cima ficaria assim:

describe Usuario do
  it {should validate_presence_of :nome }
  it {should validate_presence_of :idade }
end

Para que o RSpec reconheça esses matchers do Remakable é preciso um último detalhe de configuração que é adicionar um require do remarkable no seu spec_helper.rb logo abaixo do require ‘rspec/rails’

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'remarkable/active_record'

Shoulda

O shoulda ficou muito famoso sendo utilizado com o TestUnit, mas existe um sub-projeto dele que é o ‘shoulda-matchers’, atualmente na versão 1.0.0.beta1, que é a gem que vamos usar com o Rails 3 o RSpec 2. Adicione ao seu Gemfile as dependências:

gem "rspec"
gem "rspec-rails"
gem "shoulda-matchers"

Curiosamente para esses casos mais básicos o matcher do Shoulda é idêntico ao do Remakable e o código de teste fica idêntico ao dele:

describe Usuario do
  it {should validate_presence_of :nome }
  it {should validate_presence_of :idade }
end

Dessa vez não é preciso nenhuma configuração extra, basta apenas executar os testes e:  Seja uma pessoa mais feliz!

Conclusão

Ambas são ótimas opções para dar uma bombada nos seus testes, cada um com suas vantagens e desvantagens. Recomendo uma lida nas respectivas documentações para conhecer mais de cada um deles e escolher o que melhor supre suas necessidades.

Tagged with: , , ,
Posted in Rails, Testes

Meu ambiente de desenvolvimento em 7 itens

Fui convidado para a brincadeira pelo Adriano Almeida e pelo Anderson Leite e aí vamos nós:

Máquina / Sistema Operacional

Minha máquina “oficial” é meu macbook white 13″ que já está comigo desde 2008, mas com 4Gb e com upgrade pro Snow Leopard.

Editor

Pra arquivos texto no geral e RoR tenho e uso bastante o TextMate. Já dei algumas chances pro Vim, mas ainda não me adaptei perfeitamente, recentemente decidi lhe dar outra e parece que agora vou ficar com ele mesmo. Estou usando as configurações do Akita e o Bundle de afc que o Adriano fez. (afc é o formato que usamos pra escrever as apostilas da Caelum – Quem já teve curiosidade, conheça o Tubaina).
Pra programar java não abro mão do Eclipse!

Terminal

O bom e velho bash mesmo. Algumas poucas frescuras no ~/.bash_profile pra adicionar cores e personalizar o PS1, mas nada de mais. Normalmente meu terminal está uma zona com pelo menos umas 5 ou 6 abas abertas. Costumo ter umas 2 ou 3 por projeto (server, testes e “outros”) e quase sempre tenho abas de mais de projeto aberta.

Browser

Hoje meu browser principal é o Chrome, tanto pro dia-a-dia quanto pra desenvolvimento, mas tenho e uso o FF e o Safari. Assim como meu Terminal, meu browser também é uma salada de abas, mas piorada. Aqui tenho umas abas que ficam semanas abertas aguardando para serem lidas.

Software

QuickSilver, Adium, Skype, TweetDeck, DropBox e Keynote, além dos indispensáveis serviços do Google: GMail, Calendar e Docs.

Source-code

Felizmente tenho usado apenas o git hoje em dia.

Música

Quando preciso de muita concentração coloco meus fones e um bom Power Metal pra me isolar do mundo. Independente disso, gosto bastante de ouvir música enquanto programo, mas dentro da Caelum acabo ficando com o volume mais baixo ou com o fone em apenas 1 dos ouvidos pra ouvir as discussões. Um ponto curioso sobre as músicas comigo é que não posso ouvir uma música que me empolga e eu não conheço ela perfeitamente (saber tocar e/ou cantar). Ou escuto uma música que domino ou uma música neutra, se não ela passa a atrapalhar ao invés de ajudar. Para conhecer meu gosto musical recomendo uma passada no meu perfil no Last.fm

Os meus convidados são: Todos autores do Vida Geek

Posted in Uncategorized