<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9058337287611971869</id><updated>2012-01-30T20:09:12.707-02:00</updated><category term='apache'/><category term='linux'/><category term='ruby'/><category term='rails na prática'/><category term='dry'/><category term='orientação a objetos'/><category term='javascript'/><category term='google maps'/><category term='mysql'/><category term='java'/><category term='cache'/><category term='php'/><category term='testes automatizados'/><category term='video aula'/><category term='desenvolvimento ágil'/><category term='mac os x'/><category term='dicas de programação'/><category term='cucumber'/><category term='textmate'/><category term='software livre'/><category term='open source'/><category term='evento'/><category term='jedit'/><category term='gnome'/><category term='servidores web'/><category term='slackware'/><category term='jquery'/><category term='rspec'/><category term='mergetool'/><category term='tratamento de imagens'/><category term='scrum'/><category term='css'/><category term='git'/><category term='gem'/><category term='smarty'/><category term='web 2.0'/><category term='rails'/><category term='gimp'/><category term='uml'/><category term='layouts'/><category term='traduções'/><category term='vim'/><category term='livros'/><category term='ubuntu'/><category term='bdd'/><category term='editores de texto'/><category term='desenvolvimento web'/><category term='rake'/><title type='text'>Blog do Grasselli</title><subtitle type='html'>Ruby on Rails, metodologias ágeis e desenvolvimento web em geral</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default?start-index=101&amp;max-results=100'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>106</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8754019919563215178</id><published>2011-01-02T17:18:00.000-02:00</published><updated>2011-01-02T17:18:33.532-02:00</updated><title type='text'>Meu ambiente de desenvolvimento</title><content type='html'>O pessoal da comunidade Ruby começou com a ideia de cada um descrever seu ambiente de trabalho em seu blog e passar a bola para outros desenvolvedores. O &lt;a href="http://rafaelrosafu.com/meu-ambiente-de-desenvolvimento-em-7-itens"&gt;Rafael Rosa&lt;/a&gt; me pois na brincadeira e estou aqui postando o meu ambiente. É uma boa pra ver se eu animo a postar no blog de novo, desde o começo de outubro que eu não posto.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Máquina / Sistema operacional&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Atualmente tenho trabalhado em um Mac mini, com sistema operacional Mac OS X (Snow Leopard). Na verdade aonde estou estamos usando estações de pareamento, são 3 Mac minis, cada um com dois teclados, dois mouses e dois monitores, e 5 ou 6 desenvolvedores se revezam para usá-los.&lt;br /&gt;&lt;br /&gt;Ainda não estou muito certo se prefiro linux ou mac para trabalhar, sempre usei linux no serviço (geralmente ubuntu) e um macbook em casa. Ultimamente estou com mac no serviço também, a experiência está sendo boa apesar de que por algum estranho motivo eu me sinto mais rápido num linux. Talvez eu goste mais do terminal do linux.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Terminal&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Como um desenvolvedor ruby tenho a felicidade de ter um terminal aberto 100 % do meu tempo. Não conseguiria trabalhar com um sistema operacional sem um bom terminal.&lt;br /&gt;&lt;br /&gt;Geralmente deixo uma aba aberta para o log do servidor local e outra para uso genérico. Quando estou no Linux costumo usar o Vim dentro do terminal como editor de textos, então uma aba fica reservada pra ele. No mac acabo usando o Mvim, porque no terminal do mac o vim não fica muito legal.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Editor&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Como já falei no tópico acima, meu editor de textos é o Vim. Já uso ele há uns 2 ou 3 anos e não o troco por nenhum outro. Lógico que em algumas linguagens uma IDE é totalmente necessária, mas como trabalho com Ruby um bom editor de textos (como o Vim) é mais do que suficiente.&lt;br /&gt;&lt;br /&gt;Não uso o vim porque me acho mais rápido com ele ou algo do gênero. Uso ele por afinidade mesmo. Me sinto muito bem com ele, gosto de aprender comandos novos com frequência e acho ele uma ideia genial. E, lógico, depois de um tempo usando me tornei mais rápido nele do que nos outros.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Navegador&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Para desenvolver eu sou 100% Firefox, não consigo usar outro. Para uso pessoal eu já passei por vários, opera, firefox, chrome e já faz uns meses que estou testando o Safari, tenho gostado.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Outros&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Bom, é isso, dentre outras coisas uso o Git para versionamento, algumas ferramentas que desenvolvo para uso pessoal para facilitar algumas tarefas, como o Donald para solucionar conflitos no Git. Uma boa ferramenta de integração contínua é essencial em uma equipe também. Não escuto música enquanto desenvolvo, mas converso bastante.&lt;br /&gt;&lt;br /&gt;Passo a bola pro &lt;a href="http://twitter.com/rbernardelli"&gt;Ricardo Bernardelli&lt;/a&gt;, &lt;a href="http://twitter.com/renatocn"&gt;Renato Nitta&lt;/a&gt; e para o &lt;a href="http://twitter.com/mauricioamorim"&gt;Maurício de Amorim&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Abraços.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8754019919563215178?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8754019919563215178/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8754019919563215178' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8754019919563215178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8754019919563215178'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2011/01/meu-ambiente-de-desenvolvimento.html' title='Meu ambiente de desenvolvimento'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4909600788288077389</id><published>2010-10-14T22:41:00.000-03:00</published><updated>2010-10-14T22:41:03.544-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><title type='text'>Como sua equipe lida com open source?</title><content type='html'>Nos últimos anos tenho a felicidade de ter trabalhado em equipes que utilizam open source para o desenvolvimento de suas aplicações e percebo entre as equipes algumas diferenças em como elas lidam com isso.&lt;br /&gt;&lt;br /&gt;Acredito que a partir do momento que você escolhe usar tecnologias abertas, a forma com que sua equipe lida com esse tipo de desenvolvimento pode ser crucial para a produtividade e o bom andamento do projeto.&lt;br /&gt;&lt;br /&gt;Vou listar alguns comportamentos diferentes que você pode ter:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Acho que Open source é como qualquer outro tipo de software (Rendimento baixo)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Você, ou sua equipe, acha que open source é como qualquer outra forma de desenvolvimento, a única diferença é que ela na maioria das vezes é gratuita.&lt;/li&gt;&lt;li&gt;Você acha que ela está lá para te servir, que basta instalar, rodar, e tudo tem que funcionar como as outras tecnologias fechadas que você está acostumado.&lt;/li&gt;&lt;li&gt;Você reclama quando encontra falhas na aplicação, e começa a usar isso de desculpa para o desempenho da equipe.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Pode até ser que, em projetos maiores e mais consolidados (ubuntu, mysql, apache), um comportamento como esse não seja tão prejudicial. Mas pensando em projetos menores, como o próprio Rails ou Ruby Gems, uma postura como essa não lhe trará um bom aproveitamento.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Sou apenas um usuário (Rendimento médio)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Você entende melhor como funciona o desenvolvimento open source, mas se posiciona como mero usuário.&lt;/li&gt;&lt;li&gt;Se algo não atende suas necessidades você procura por outras soluções ou espera até que o problema seja resolvido.&lt;/li&gt;&lt;li&gt;Você acha que é um grande problema quando algo assim acontece, pois sabe que vai impactar o rendimento da equipe.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Esse tipo de comportamento é um pouco melhor do que o anterior. Equipes em que trabalhei que agiam assim com o tempo até acabavam sendo mais críticas para escolher entre as tecnologias (vendo se o projeto ainda é ativo, reputação, etc) e acabavam contornando problemas, mas ainda eram meros usuários e de vez em quando travavam por problemas não tão complexos.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Eu contribuo (Rendimento alto)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sua equipe sabe o que é open source e lida com ele com espírito de contribuição&lt;/li&gt;&lt;li&gt;Se algo não atende suas necessidades você:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;faz um fork do projeto e manda um patch pra equipe que o está desenvolvendo&lt;/li&gt;&lt;li&gt;cria um outro projeto open que faça o que você precisa (se os que existem são muito diferentes da sua necessidade)&lt;/li&gt;&lt;li&gt;entra em contato com com a equipe que o desenvolve e reporta o seu problema (e se possível os ajuda a solucioná-lo)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Fica feliz quando encontra um bug pois ve uma oportunidade de contribuir&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Essa situação eu encontrei na equipe que trabalho no momento (&lt;a href="http://gonow.com.br/"&gt;Gonow&lt;/a&gt;) e foi surpreendente ver o quão mais produtivo é trabalhar assim.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Contribuindo para os projetos você atende suas necessidades de uma forma mais rápida. Você não precisa esperar até que alguém resolva seu problema, o código está lá e equipes open source são extremamente receptivas e gratas por receber patches e novas features (portanto que sigam o foco do projeto e as regras para contribuição).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Contribuir não é tão difícil quanto parece, você vai melhorando aos poucos, vai entendendo melhor como cada projeto funciona, aumenta sua capacidade de ler e entender código dos outros, ve bons exemplos de códigos, entre outros. Só há ganhos.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Você até treina seu inglês!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lançar projetos open source também é de grande valia.&amp;nbsp;Em um projeto la na Gonow precisávamos de algo que calculasse distâncias entre lugares. Existiam gems que calculavam mas todas faziam isso a partir do raio, nenhuma fazia a partir da rota. Desenvolvemos nossa solução para isso (o &lt;a href="http://github.com/gonow/go_maps"&gt;go_maps&lt;/a&gt;) e o lançamos como open source. Tivemos ganhos logo nos primeiros dias, pois alguns usuários reclamaram de coisas que ele não tinha e percebemos que íamos precisar também. Tivemos esse feedback antes mesmo de lançar nosso projeto aos clientes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Portanto fica a dica, se você pretende usar open source, saiba que não é apenas um software gratuito, ele é um software colaborativo. Incentive sua equipe a contribuir, se possível dediquem tempo do próprio projeto para isso, uma vez que esses softwares são parte do projeto.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;É isso pessoal, nos vemos amanhã no Rails Rumble!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4909600788288077389?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4909600788288077389/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4909600788288077389' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4909600788288077389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4909600788288077389'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/10/como-sua-equipe-lida-com-open-source.html' title='Como sua equipe lida com open source?'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2764710357035199435</id><published>2010-09-15T22:04:00.000-03:00</published><updated>2010-09-15T22:04:51.963-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento ágil'/><title type='text'>Ser ágil não é fácil</title><content type='html'>Trabalhando há algum tempo em equipes ágeis percebo que algumas coisas não são muito bem compreendidas por quem decide formar uma equipe assim, em boa parte dos casos.&lt;br /&gt;&lt;br /&gt;O que mais percebo em conversas, ou até em algumas equipes que já trabalhei, é que o desenvolvimento ágil muitas vezes é visto pelo gerente como uma ferramenta para motivar a equipe. O pessoal fica feliz porque está trabalhando com tendências da moda, cola post it aqui e ali e tudo flui bem, tudo continua como era antes, apenas diminuímos a documentação.&lt;br /&gt;&lt;br /&gt;Se você pensa assim, saiba que pode está cometendo um grande erro e você pode levar seu projeto a falência.&lt;br /&gt;&lt;br /&gt;Ser ágil não é fácil como parece, os princípios por trás do manifesto exigem uma equipe muito bem preparada.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nossa maior prioridade é satisfazer o cliente, através da entrega adiantada e contínua de software de valor.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;O principal objetivo de ser ágil é entregar valor ao cliente, entregar cedo e de forma contínua. Para chegar a esse objetivo você não vai desenvolver em módulos, fazer toda uma parte do sistema e depois ir pra outra e não voltar nessa parte tão cedo. Você vai desenvolver um todo, que funciona, de forma simples, e ficar melhorando todas as partes desse todo incrementalmente e continuamente.&lt;br /&gt;&lt;br /&gt;Isso exige muito mais maturidade da equipe do que um projeto não ágil. Para fazer essa refatoração contínua (e criação de novas funcionalidades) nesse sistema em constante mudança você vai precisar de, no mínimo, uma ótima cobertura de testes.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Aceitar mudanças de requisitos, mesmo no fim do desenvolvimento. Processos ágeis se adequam a mudanças, para que o cliente possa tirar vantagens competitivas.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Se entrega de valor já faz com que você tenha que adaptar e evoluir um código constantemente, imagine mudanças de requisitos no meio do projeto.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Aonde eu quero chegar&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;O que eu estou querendo dizer com isso tudo é que desenvolvimento ágil na minha opinião é a maneira mais eficaz de se desenvolver software, se a decisão for minha eu com certeza vou optar por ela. Mas que fique bem claro que essa é uma forma de desenvolvimento difícil, que exige bastante da equipe.&lt;br /&gt;&lt;br /&gt;Chegaria até a dizer que não é viável criar uma equipe ágil apenas com desenvolvedores inexperientes. Digo isso porque geralmente uma equipe iniciante, para atender à demanda flexível de um projeto ágil, acaba criando código difícil de lidar e, em pouco tempo, gera um projeto engessado, difícil de expandir.&lt;br /&gt;&lt;br /&gt;Lembre-se:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Processos ágeis promovem um ambiente sustentável. Os patrocinadores, desenvolvedores e usuários, devem ser capazes de manter indefinidamente, passos constantes.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A velocidade de entrega de valor deve ser constante, mesmo após um tempo de projeto.&lt;br /&gt;&lt;br /&gt;Se você gerente, deseja formar uma equipe ágil, tome essa decisão de forma consciente, sabendo que há muito trabalho à fazer, que será preciso investir na equipe. Que desenvolvimento ágil exige muito comprometimento por parte de todos e aponta falhas.&lt;br /&gt;&lt;br /&gt;Uma vez que você sabe que desenvolvimento ágil não é mais fácil ou mais tranquilo que os demais e mesmo assim deseja adotá-lo, querendo obter o real valor dele, seja bem vindo =)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2764710357035199435?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2764710357035199435/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2764710357035199435' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2764710357035199435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2764710357035199435'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/09/ser-agil-nao-e-facil.html' title='Ser ágil não é fácil'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6637191611757852073</id><published>2010-08-25T23:39:00.000-03:00</published><updated>2010-08-25T23:39:32.646-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento ágil'/><category scheme='http://www.blogger.com/atom/ns#' term='testes automatizados'/><category scheme='http://www.blogger.com/atom/ns#' term='bdd'/><title type='text'>Porque eu escrevo os testes antes</title><content type='html'>Depois de um bom tempo insistindo, e com a ajuda também do pessoal da minha equipe que sempre incentivou (exigiu? =P) essa prática, hoje em dia já se tornou natural para mim escrever o teste antes da implementação.&lt;br /&gt;&lt;br /&gt;Minha ideia ao escrever esse post é lhe dizer alguns motivos de porque eu acho que você também deveria fazer isso.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#1 Uma prática de design&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Já dizia o pessoal do livro The Rspec Book que BDD não é uma prática de testes e sim uma prática de design. Usamos o BDD para nos guiar sobre o que deve ser criado para satisfazer as necessidades de nosso produto, sem desperdícios. Se você escreve o teste depois você não se beneficia disso.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#2 Não se influenciar pela implementação&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Quando você escreve o teste você deve se concentrar no que você espera de sua aplicação, sem pensar em como você vai implementar isso. Se você pensar na implementação antes ou, pior, você implementar antes do teste, você pode criar um teste influenciado pela implementação. O que pode fazer com que sua implementação tenha mais coisa do que o necessário e, ainda, pode fazer com que seu teste saiba demais sobre a implementação e a engesse.&lt;br /&gt;&lt;br /&gt;Você deveria poder trocar a implementação sem precisar alterar o teste (refatoração), se seu teste sabe demais sobre a implementação, talvez você não consiga fazer isso e tenha grandes prejuízos (todo mundo tem que ficar alterando os testes a cada mudança).&lt;br /&gt;&lt;br /&gt;Escrever o teste antes vai deixar seu código mais enxuto e sem desperdícios, focando apenas no necessário.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#3 Mais fácil se certificar que o teste funciona&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Quando você escreve o teste antes você faz com que ele falhe e, após a implementação, ele deve passar. Isso já é uma prova de que seu teste está cobrindo o que você está criando. Se você escreve o teste depois você não tem tanta certeza sobre essa cobertura e, se você não tem o costume de retroceder a parte implementada pra ver se o teste realmente falha, talvez você crie testes que não cubram nada de novo.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#4 Não ter o "dever" de escrever o teste depois&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Se você escreveu antes você usufruiu de diversos benefícios e no final já estava com tudo pronto, o teste realmente se mostra parte do desenvolvimento (o que ele é de fato). Se você não o fez, no final de tudo você ainda tem que escrever os testes, o que pode parecer um fardo (tudo está "pronto" e eu tenho que "perder" tempo com o teste).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Concluindo&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Se sua equipe escreve testes depois, eu lhe digo que vale muito a pena tentar mudar essa ordem. Diria até que não faz sentido escrever o teste depois.&lt;br /&gt;&lt;br /&gt;Não é tão difícil assim obter essa prática, basta um pouco de disciplina e, se precisar de ajuda, dicas sobre como testar determinada coisa, me coloco a disposição pra conversar. Não sou nenhum expert de testes, mas gosto bastante de falar sobre o assunto, me adiciona no gtalk, e-mail, twitter ou o que você preferir que eu tento ajudar com o que eu puder.&lt;br /&gt;&lt;br /&gt;Até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6637191611757852073?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6637191611757852073/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6637191611757852073' title='5 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6637191611757852073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6637191611757852073'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/08/porque-eu-escrevo-os-testes-antes.html' title='Porque eu escrevo os testes antes'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4029547882569466159</id><published>2010-08-21T15:59:00.005-03:00</published><updated>2010-08-21T16:13:04.347-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rspec'/><category scheme='http://www.blogger.com/atom/ns#' term='testes automatizados'/><title type='text'>Identificando specs lentos com rspec</title><content type='html'>Recentemente em um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;projeto&lt;/span&gt; me passaram a tarefa de diminuir o tempo de execução dos testes, para facilitar a integração contínua.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lembrei então de um comando  do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;rspec&lt;/span&gt; que havíamos usado em um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;projeto&lt;/span&gt; anterior que facilita muito a tarefa de identificar quais são os testes críticos.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Não sei quantos conhecem (eu não conhecia há dois &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;projetos&lt;/span&gt; atrás), mas um dos formatos do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;rspec&lt;/span&gt; é o "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;profile&lt;/span&gt;", que mostra no final dos testes um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;top&lt;/span&gt; 10  dos mais lentos e o tempo que cada um demorou.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Basta executar assim:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="color:#000099;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;spec&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;spec&lt;/span&gt;/ -f &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;profile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ou, em sua versão resumida:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="color:#000099;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;spec&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;spec&lt;/span&gt;/ -f o&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;O resultado é similar ao abaixo:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Profiling&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;enabled&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;..................&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;Top&lt;/span&gt; 10 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;slowest&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;examples&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0011200 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;variable&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;not&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;seted&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;up&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;with&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;with&lt;/span&gt; --vim &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;argument&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;call&lt;/span&gt; vim&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0010110 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;variable&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;not&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;seted&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;up&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;with&lt;/span&gt; no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;send&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;an&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;error&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;message&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0009800 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;variable&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;not&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;seted&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;up&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;with&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;with&lt;/span&gt; no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;arguments&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_55"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;call&lt;/span&gt; vim&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0009340 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_58"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;variable&lt;/span&gt; as mate &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_61"&gt;with&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_62"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_63"&gt;with&lt;/span&gt; no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_64"&gt;arguments&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_65"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_66"&gt;call&lt;/span&gt; mate&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0009170 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_67"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_68"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_69"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_70"&gt;variable&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_71"&gt;not&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_72"&gt;seted&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_73"&gt;up&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_74"&gt;with&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_75"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_76"&gt;with&lt;/span&gt; --&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_77"&gt;gvim&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_78"&gt;argument&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_79"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_80"&gt;call&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_81"&gt;gvim&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0008920 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_82"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_83"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_84"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_85"&gt;variable&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_86"&gt;not&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_87"&gt;seted&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_88"&gt;up&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_89"&gt;with&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_90"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_91"&gt;with&lt;/span&gt; -g &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_92"&gt;argument&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_93"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_94"&gt;call&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_95"&gt;gvim&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0008910 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_96"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_97"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_98"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_99"&gt;variable&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_100"&gt;not&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_101"&gt;seted&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_102"&gt;up&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_103"&gt;with&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_104"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_105"&gt;with&lt;/span&gt; -t &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_106"&gt;argument&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_107"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_108"&gt;call&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_109"&gt;textmate&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0008830 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_110"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_111"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_112"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_113"&gt;variable&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_114"&gt;not&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_115"&gt;seted&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_116"&gt;up&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_117"&gt;with&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_118"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_119"&gt;with&lt;/span&gt; --&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_120"&gt;mvim&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_121"&gt;argument&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_122"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_123"&gt;call&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_124"&gt;mvim&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0008820 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_125"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_126"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_127"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_128"&gt;variable&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_129"&gt;not&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_130"&gt;seted&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_131"&gt;up&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_132"&gt;with&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_133"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_134"&gt;with&lt;/span&gt; --&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_135"&gt;textmate&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_136"&gt;argument&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_137"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_138"&gt;call&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_139"&gt;textmate&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;0.0008750 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_140"&gt;Donald&lt;/span&gt;::&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_141"&gt;MergeTool&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_142"&gt;with&lt;/span&gt; $EDITOR &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_143"&gt;variable&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_144"&gt;not&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_145"&gt;seted&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_146"&gt;up&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_147"&gt;with&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_148"&gt;unmerged&lt;/span&gt; files &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_149"&gt;with&lt;/span&gt; -m &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_150"&gt;argument&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_151"&gt;should&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_152"&gt;call&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_153"&gt;mvim&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_154"&gt;Finished&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_155"&gt;in&lt;/span&gt; 0.026412 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_156"&gt;seconds&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;18 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_157"&gt;examples&lt;/span&gt;, 0 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_158"&gt;failures&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4029547882569466159?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4029547882569466159/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4029547882569466159' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4029547882569466159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4029547882569466159'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/08/identificando-specs-lentos-com-rspec.html' title='Identificando specs lentos com rspec'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-3248774840697017268</id><published>2010-06-03T13:53:00.009-03:00</published><updated>2010-06-03T14:25:14.668-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Como eu uso o GIT</title><content type='html'>&lt;div&gt;Recentemente vi &lt;a href="http://yehudakatz.com/2010/05/13/common-git-workflows/"&gt;um post do Yehuda Katz&lt;/a&gt; sobre como ele usa o GIT e me empolguei para escrever também.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Antes de mais nada, gostaria de dar os devidos créditos ao &lt;a href="http://twitter.com/rogerio_augusto"&gt;@rogerio_augusto&lt;/a&gt; porque foi ele quem me ensinou boa parte dos itens que vou escrever hoje.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Pull e Push&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bom, vou começar pelo mais básico, enviar e receber commits do repositório remoto.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Geralmente o pessoal acredita que a fórmula é essa:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;commito alguma coisa&lt;/li&gt;&lt;li&gt;faço pull para ver se tem alguma coisa no remoto&lt;/li&gt;&lt;li&gt;faço push para enviar para ele&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Isso até que funciona, mas eu prefiro uma outra abordagem que deixa a árvore dos commits mais organizada.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;O pull nada mais é do que um fetch (baixa objetos e referências do remoto) mais merge (junta duas ou mais histórias).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Imagine que você baixou tudo que estava no remoto e fez um commit. Enquanto você trabalhava outra pessoa enviou alguma coisa para o remoto que você não tem. Se você fizer um pull, a árvore dos commits ficará assim:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para não ter que criar um repositório remoto para o exemplo, eu fiz o merge entre dois repositórios locais, mas o resultado é o mesmo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Com o merge ele mostra que os commits foram feitos em paralelo, mas as vezes essa informação não é tão relevante, e vale mais a pena deixar a árvore organizada. Por isso quando eu vou fazer isso, ao invés de eu dar um pull pro remoto, eu faço um rebase. Por exemplo:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_CGnpveaIy_M/TAffHwFBh3I/AAAAAAAAASo/GqO63-26Zfc/s1600/exemplo_git.png"&gt;&lt;img src="http://2.bp.blogspot.com/_CGnpveaIy_M/TAffHwFBh3I/AAAAAAAAASo/GqO63-26Zfc/s400/exemplo_git.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5478592795977549682" style="cursor: pointer; width: 244px; height: 58px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git rebase origin/master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ou, mais fácil de usar&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git pull --rebase origin master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Com o rebase o git faz um stash de seus commits que ainda não existem no remoto, baixa os branchs do remoto e recoloca seus commits após o que veio dele. Ficaria assim:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_CGnpveaIy_M/TAffHz1TrII/AAAAAAAAASw/ieN74GUUG-Y/s1600/exemplo_git_2.png"&gt;&lt;img src="http://4.bp.blogspot.com/_CGnpveaIy_M/TAffHz1TrII/AAAAAAAAASw/ieN74GUUG-Y/s400/exemplo_git_2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5478592796985371778" style="cursor: pointer; width: 168px; height: 43px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Viram? O git passou o seu commit para depois dos commits que vieram do repositório (apesar deles poderem ter ocorrido antes) e assim manteve a árvore organizada e fácil de entender.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tem gente que fala que assim você perde a real história dos commits, mas eu discordo. Para casos em que a história é relevante eu uso o pull normal para deixar registrado o que aconteceu (por exemplo, estou criando uma aplicação a partir de uma outra open source e a original foi atualizada, aí sim eu faço um pull para mostrar que são commits de equipes diferentes que andaram em paralelo), mas para os casos de commits dentro da mesma equipe trabalhando numa mesma tarefa, acho que vale mais a árvore se manter legível.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Merge com a opção squash&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Geralmente eu uso branchs para separar as histórias do projeto que estão sendo criadas, sendo assim, imagine a seguinte situação:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Você criou um branch a partir do master para fazer sua história. Nesse seu branch você fez 23 commits, que foram totalmente úteis para você se organizar, integrar mais facilmente, etc.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Então você terminou sua história e vai fazer o merge para mandar sua nova funcionalidade para o remoto, então você faz:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git pull origin master (imaginando que você não commitou nada no seu master, senão o mais correto é git pull --rebase)&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout seu_branch&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git rebase master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git merge seu_branch&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git push origin master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Com isso você atualizou seu master, integrou as atualizações do master com o seu branch, fez o merge do seu branch no master e aí sim enviou os seus 23 commits.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Até aí você fez tudo perfeitamente, mas existe uma outra ferramenta que pode te ajudar a se organizar, a opção --squash do merge.&lt;/div&gt;&lt;div&gt;Quando você faz o merge com --squash (git merge seu_branch --squash) o git leva as atualizações pro seu branch mas como se elas não tivessem sido commitadas. Aí você faz um único commit e manda só ele para o master.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para quem está olhando o master, faz mais sentido ver um commit por funcionalidade, enquanto para quem está desenvolvendo a funcionalidade os 23 commits são úteis. Então agindo assim a gente ajuda todo mundo. Ficaria assim:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git pull origin master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout seu_branch&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git rebase master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git merge seu_branch --squash&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git commit -am "Minha funcionalidade"&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git push origin master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Opção stash do git merge&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Uma outra ferramenta útil é o stash. Imagine que você vai fazer uma atualização pequena no seu projeto e resolveu fazer no branch master mesmo (para aplicações que dividem o projeto em dois remotos - produção e desenvolvimento - eu acho isso totalmente normal). Só que enquanto você está fazendo você percebe que será uma atualização grande e seria mais interessante fazer isso num branch a parte (ou alguém te chamou para fazer outra coisa e você não vai poder continuar aquilo no momento). Então você está com algumas modificações sem commitar mas você não vai poder commitar no master, porque não está concluído, etc.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para isso você pode usar o stash, você faria assim:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git stash (o git guarda todas as suas modificações em um lugar a parte e seu branch atual passa a ficar como se ninguém tivesse mexido - você pode usar git status para confirmar)&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout -b seu_branch_novo&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git stash apply (suas modificações voltam a aparecer, pode confirmar com git status)&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git commit -am "Primeiro commit da minha funcionalidade"&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git stash clear (apaga tudo o que estava no stash)&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Com isso você fez como se tivesse começado desde o início em um branch novo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Você consegue também criar e gerenciar mais de um stash, mas geralmente um só satisfaz minha necessidade.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Opção track do git branch&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Vamos a mais uma situação. Seu colega começou uma funcionalidade em um branch a parte e depois de alguns dias pediu para você ajudar ele nessa tarefa.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Você tem que trabalhar nesse mesmo branch dele, então você decide criar o branch dele localmente. Você faz:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git branch branch_dele&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout branch_dele (você poderia ter usado git checkout -b branch_dele e fazer tudo de uma vez)&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git pull origin branch_dele&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;CUIDADO!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Quando você fez o primeiro comando você criou um novo branch a partir do que você tem em seu branch atual. E pode ser que você tem coisas nele que não deveriam estar no branch do seu colega, pode ser até conflitante com as tarefas dele e além disso o merge vai bagunçar legal a árvore dele. Se você fizer um rebase pode até piorar mais porque você terá que dar um --force para reescrever a história dele e ele terá que se atualizar. Bom, enfim, essa situação pode gerar resultados não esperados.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para isso o mais indicado seria:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git branch branch_dele --track origin/branch_dele&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git checkout branch_dele&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Com a opção --track o git vai criar o branch a partir do que tem no brach remoto que você informou, sem olhar para o que tem no seu branch atual. Sendo assim você ficará com o branch idêntico ao do seu colega, o que é o ideal para essa situação.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;O git fetch antes é importante porque o --squash vai criar o branch com as informações que estiverem no repositório local, não no remoto. Faça o fetch para atualizar o repositório local antes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Voltando commits&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Outra coisa útil é conseguir voltar atrás em algo que está fazendo. Por exemplo:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Você começou uma tarefa e percebe que está indo na direção errada e deseja começar de novo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Se você ainda não fez nenhum commit basta usar:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git reset --hard&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;E você voltará ao estado do último commit efetuado.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Se você já tinha commitado algo, então você pode fazer:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git reset --hard id_do_seu_commit&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Exemplo:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git reset --hard dbeeeb0369b5bad0f776fc5ae16c5500bd808156&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Com o reset você consegue ir para trás e para frente. Para pegar o id de um commit que está a frente você pode usar:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;git reflog&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Acabou&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bom, tentei lembrar de algumas situações que são comuns em um projeto. Espero ter ajudado e gostaria da opinião de vocês. Pode ser que existam outras abordagens melhores, então estou aberto para discutir e aprender.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Qualquer dúvida podem entrar em contato comigo (comentário, gtalk, &lt;a href="http://twitter.com/grasselli"&gt;twitter&lt;/a&gt;, email etc).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Abraços.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-3248774840697017268?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/3248774840697017268/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=3248774840697017268' title='6 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3248774840697017268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3248774840697017268'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/06/como-eu-uso-o-git.html' title='Como eu uso o GIT'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/TAffHwFBh3I/AAAAAAAAASo/GqO63-26Zfc/s72-c/exemplo_git.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6402067559170396562</id><published>2010-05-01T11:06:00.004-03:00</published><updated>2010-05-01T11:41:26.238-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Usando nested attributes com single table inheritance</title><content type='html'>Esses dias no serviço precisamos usar &lt;a href="http://martinfowler.com/eaaCatalog/singleTableInheritance.html"&gt;single table inheritance&lt;/a&gt; em alguns models do nosso projeto.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Por exemplo, eu tenho a classe:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/386381.js?file=question.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;E duas outras que herdam dela:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="http://gist.github.com/386381.js?file=questions_children.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Esses models utilizam a mesma tabela no banco de dados (&lt;b&gt;questions&lt;/b&gt;) que contém uma coluna "&lt;b&gt;type&lt;/b&gt;" que diz se a questão é uma MultipleChoiceQuestion ou é uma SingleChoiceQuestion.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;O problema é que ao usar esses models em um formulário aninhado com &lt;b&gt;accepts_nested_attributes&lt;/b&gt;, por mais que eu colocasse um hidden_field dizendo qual era o &lt;b&gt;type&lt;/b&gt; da question, o Rails não salvava ele (o campo ficava nulo no banco).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Procurando pela internet encontrei uma solução que achei interessante e resolveu meu problema. Foi uma resposta que o &lt;a href="http://stackoverflow.com/questions/2553931/can-nested-attributes-be-used-in-combination-with-inheritance"&gt;KandadaBoggu&lt;/a&gt; deu no fórum &lt;a href="http://stackoverflow.com/questions/2553931/can-nested-attributes-be-used-in-combination-with-inheritance"&gt;stackoverflow&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;O atributo type é protegido por padrão em classes que herdam de ActiveRecord::Base, para solucionar o problema podemos sobrescrever o método que define isso na nossa classe question:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;script src="http://gist.github.com/386381.js?file=question2.rb"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6402067559170396562?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6402067559170396562/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6402067559170396562' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6402067559170396562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6402067559170396562'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/05/usando-nested-attributes-com-single.html' title='Usando nested attributes com single table inheritance'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-3640305378896355595</id><published>2010-04-25T19:55:00.004-03:00</published><updated>2010-04-25T20:06:33.388-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>Gem donald versão 0.1.4</title><content type='html'>Ontem a noite lancei mais uma versão da gem Donald, dessa vez consegui adicionar algumas features novas.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Donald é uma gem que eu fiz para tratar conflitos do GIT, quando o conflito ocorre você executa o comando "donald" e ela abre os arquivos conflitados no seu editor de texto favorito (no início ela foi desenvolvida para o vim, mas aí abri espaço para outros editores).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Novas features:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Abrir arquivos no vim já procurando por conflitos:&lt;/b&gt; agora quando você estiver usando o vim (mvim e gvim também) a gem já abrirá os arquivos fazendo uma busca por "HEAD", que é um texto comum a todos os conflitos. Sendo assim basta apertar "n" para ir para o próximo conflito.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Configurar seu editor padrão: &lt;/b&gt;agora você pode configurar o editor de textos que mais usa (se não for o vim) para que o Donald utilize ele por padrão sem ser necessário passar nenhum parâmetro adicional. Para isso basta configurar a variável padrão $EDITOR em seu sistema.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Um jeito de fazer isso é adicionar a seguinte linha ao arquivo ~/.bashrc&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;export EDITOR="mate"&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Isso é um exemplo para configurar o textmate como o editor padrão. Você pode até configurar um editor que a gem não cobre, como o gedit, por exemplo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para maiores informações visitem o &lt;a href="http://github.com/BrunoGrasselli/donald"&gt;repositório do projeto&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para atualizar sua gem execute:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;sudo gem update donald&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Abraços.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-3640305378896355595?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/3640305378896355595/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=3640305378896355595' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3640305378896355595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3640305378896355595'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/04/gem-donald-versao-014.html' title='Gem donald versão 0.1.4'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4647032064438146049</id><published>2010-04-21T20:31:00.003-03:00</published><updated>2010-04-21T20:40:19.477-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>Gem donald versão 0.1.3</title><content type='html'>Lancei hoje uma nova atualização para a gem donald.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para atualizar execute:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;sudo gem update donald&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Havia uma situação do git que ela não cobria (both modified). E diga-se de passagem é uma situação bem comum.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Fiz essa correção hoje e estou disponibilizando, para quem usa ela é bem interessante fazer o update.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Obrigado &lt;a href="http://twitter.com/julioavero"&gt;@julioavero&lt;/a&gt; por reportar e &lt;a href="http://twitter.com/raulsouzalima"&gt;@raulsouzalima&lt;/a&gt; por me mandar o exemplo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tem algumas novas funcionalidades que pretendo adicionar à gem, como criar um arquivo de configuração para configurar seu editor padrão (e assim você conseguiria configurar qualquer editor, como o gedit por exemplo). Assim que sobrar um tempinho vou mecher nela.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Se alguém quiser adicionar qualquer funcionalidade nela ou bug fix sinta-se livre, o código fonte está em:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://github.com/BrunoGrasselli/donald"&gt;http://github.com/BrunoGrasselli/donald&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Basta fazer um fork e depois me mandar um pull request (os testes tem que continuar passando =) )&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Abraços.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4647032064438146049?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4647032064438146049/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4647032064438146049' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4647032064438146049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4647032064438146049'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/04/gem-donald-versao-013.html' title='Gem donald versão 0.1.3'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2615586637237950805</id><published>2010-04-11T16:25:00.002-03:00</published><updated>2010-04-11T16:32:53.576-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>Nova gem Params Debugger</title><content type='html'>Acabo de lançar uma nova ruby gem para me ajudar no desenvolvimento de meus projetos e acredito que possa ajudar também outras pessoas em aplicações Rails.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;É uma gem bem simples, por exemplo:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Você está criando um formulário e deseja ver o que ele está passando por parâmetro para o Rails, com a gem instalada você faz assim:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;params_debugger create&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(Aonde create é a action do controller que eu estou debugando)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Fazendo isso ele vai imprimir no terminal a última linha do log de desenvolvimento que ele achar de parâmetros para essa action, já formatada para uma melhor visualização.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Você pode usar também a opção -p para exibir sem formatação (plain):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;params_debugger -p update&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ou até passar mais de uma action:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;params_debugger -p create update&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para instalar a gem basta fazer:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;sudo gem install params_debugger&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Código fonte:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://github.com/BrunoGrasselli/params_debugger"&gt;http://github.com/BrunoGrasselli/params_debugger&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bom é isso, aguardo seus comentários.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Abraços.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2615586637237950805?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2615586637237950805/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2615586637237950805' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2615586637237950805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2615586637237950805'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/04/nova-gem-params-debugger.html' title='Nova gem Params Debugger'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-1155604506477128074</id><published>2010-04-03T17:48:00.003-03:00</published><updated>2010-04-03T17:53:26.072-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='mergetool'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='textmate'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>Gem donald atualizada</title><content type='html'>Fala pessoal,&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hoje atualizei minha gem donald.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Eu criei essa gem para facilitar na resolução de conflitos do git. Executando o comando "donald" quando os conflitos acontecem ela abre todos os arquivos conflitados no vim, um em cada aba.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Agora nessa atualização ela também tem suporte ao Textmate usando as opções -t ou --textmate (e agora ela está coberta por testes).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Mais informações em:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://github.com/BrunoGrasselli/donald"&gt;http://github.com/BrunoGrasselli/donald&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Se você já tinha ela e quer atualizar:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;sudo gem update donald&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Se ainda não tinha:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;sudo gem install donald&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Abraços.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-1155604506477128074?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/1155604506477128074/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=1155604506477128074' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1155604506477128074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1155604506477128074'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/04/gem-donald-atualizada.html' title='Gem donald atualizada'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5833254806148862602</id><published>2010-04-01T17:43:00.004-03:00</published><updated>2010-04-01T17:49:12.512-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='editores de texto'/><title type='text'>Teclado Vim</title><content type='html'>Fala pessoal,&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ultimamente estou viciado em &lt;b&gt;vim / vi&lt;/b&gt; e hoje vi uma dica que o &lt;b&gt;Rafael O. Marques&lt;/b&gt; mandou para o grupo do &lt;b&gt;GURU-SP&lt;/b&gt; que eu achei muito legal, vim aqui repassar.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Segue imagem do teclado do vim (vi / vim graphical cheat sheet), clique para ampliá-la.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_CGnpveaIy_M/S7UGbOEsBPI/AAAAAAAAASY/XuUP0QYnmvQ/s1600/vi-teclado.png"&gt;&lt;img src="http://4.bp.blogspot.com/_CGnpveaIy_M/S7UGbOEsBPI/AAAAAAAAASY/XuUP0QYnmvQ/s400/vi-teclado.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5455273588333217010" style="cursor: pointer; width: 400px; height: 283px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Espero que seja útil, abraços.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5833254806148862602?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5833254806148862602/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5833254806148862602' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5833254806148862602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5833254806148862602'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/04/teclado-vim.html' title='Teclado Vim'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_CGnpveaIy_M/S7UGbOEsBPI/AAAAAAAAASY/XuUP0QYnmvQ/s72-c/vi-teclado.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-287348165570266713</id><published>2010-03-20T19:34:00.003-03:00</published><updated>2010-03-20T19:56:53.380-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Alguns comandos úteis do Vim</title><content type='html'>Gostaria de compartilhar alguns comandos úteis que utilizo no vim no meu dia a dia. Até tentei ir pro Textmate mas não adiantou, voltei para o vim.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bom, vamos lá, no modo normal:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;dd - Exclui a linha atual inteira&lt;/li&gt;&lt;li&gt;D - Exclui a partir do caractere atual até o final da linha&lt;/li&gt;&lt;li&gt;C - Exclui a partir do caractere atual até o final da linha e entra em modo de inserção&lt;/li&gt;&lt;li&gt;ci" - Quando executado dentro de um texto entre aspas, exclui tudo que está dentro das aspas e entra em modo inserção (funciona também com ' { [ etc)&lt;/li&gt;&lt;li&gt;ct" - Exclui texto até a próxima aspa e entra em modo inserção (funciona também com ' { [ etc)&lt;/li&gt;&lt;li&gt;V - Seleciona linha inteira&lt;/li&gt;&lt;li&gt;ddp - Substitui duas linhas&lt;/li&gt;&lt;li&gt;xp - Substitui duas letras (não tão útil)&lt;/li&gt;&lt;li&gt;dw - Exclui próxima palavra&lt;/li&gt;&lt;li&gt;cw - Exclui próxima palavra e entra em modo inserção&lt;/li&gt;&lt;li&gt;s - Exclui caractere atual e entra em modo inserção&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Em modo visual:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;c - Exclui texto selecionado e entra em modo inserção&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Em modo de comando:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;:!qualquer_comando_de_terminal - Executa qualquer comando do terminal, por exemplo :!ls ou :!rake db:migrate&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pra quem tem rails.vim (bem similares aos do Textmate):&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;def + tab - Facilita criação de bloco&lt;/li&gt;&lt;li&gt;vpo + tab - validates_presence_of&lt;/li&gt;&lt;li&gt;vu + tab - validates_uniqueness_of&lt;/li&gt;&lt;li&gt;conf + tab - content_for&lt;/li&gt;&lt;li&gt;habtm + tab - has_and_belongs_to_many&lt;/li&gt;&lt;li&gt;it + tab - teste do rspec&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Bom espero que as dicas ajudem, se você souber alguma legal estou interessado em aprender, manda via comentário, e-mail, etc.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Abraços.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-287348165570266713?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/287348165570266713/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=287348165570266713' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/287348165570266713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/287348165570266713'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/03/alguns-comandos-uteis-do-vim.html' title='Alguns comandos úteis do Vim'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8226527735819834738</id><published>2010-03-20T18:43:00.007-03:00</published><updated>2010-03-21T14:52:57.265-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='mergetool'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>Donald - Gem para auxiliar a resolver conflitos do GIT com o Vim</title><content type='html'>&lt;div style="text-align: left;"&gt;Lá na empresa estamos experimentando trabalhar com integração contínua (e está apresentando ótimos resultados até agora) o que, como o nome sugere, faz com que a gente tenha que fazer mais rebases diários com o git. O que as vezes pode resultar em alguns conflitos.&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/S6VDeOherlI/AAAAAAAAASQ/BtUYY7CwCkI/s1600-h/donald.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 140px; height: 150px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/S6VDeOherlI/AAAAAAAAASQ/BtUYY7CwCkI/s400/donald.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5450837110575509074" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Com o passar do tempo os conflitos estão diminuindo usando algumas técnicas que estamos aprendendo, e fazendo a integração cada vez mais constante.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Mas de um jeito ou de outro sempre acontece algum conflito no git para resolver e eu não sou muito fã de usar merge tools, prefiro corrigir com um editor de textos qualquer (no meu caso o vim). A única parte chata disso é abrir todos os arquivos conflitados um a um.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Para resolver isso eu fiz uma pequena gem que auxilia na solução de conflitos de uma forma muito simples. Assim que ocorrem os conflitos basta invocar a gem que ela abre todos os arquivos do conflito de uma vez no vim, um em cada aba.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;A gem se chama Donald (eu estava sem criatividade pra pensar num nome e dei qualquer um =P) e funciona da seguinte forma:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Instalação:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;code&gt;sudo gem install donald&lt;/code&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Quando acontecer o conflito, basta digitar:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;code&gt;donald&lt;/code&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;E o vim será aberto com todos os arquivos em abas.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Bom é isso, fiz essa gem rapidinho pra tentar me auxiliar la no serviço (eu realmente acredito que vai ajudar). Essa foi minha primeira gem, então se tiverem dicas serão bem vindas.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Se tiver ideias também você pode ajudar fazendo um fork do meu projeto que está em:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;a href="http://github.com/BrunoGrasselli/donald"&gt;http://github.com/BrunoGrasselli/donald&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;E a gem está hospedada em:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;a href="http://rubygems.org/gems/donald"&gt;http://rubygems.org/gems/donald&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Pretendo adicionar algumas funcionalidades nela como abrir o gvim e mvim ao invés do vim, e talvez até outros editores (preciso escrever testes também).&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Abraços.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Ps. Atualizei a gem hoje (21/03/2010) e ela já tem as opções de abrir com o gvim ou mvim (--mvim, --gvim ou -m, -g).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8226527735819834738?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8226527735819834738/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8226527735819834738' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8226527735819834738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8226527735819834738'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/03/donald-gem-para-auxiliar-resolver.html' title='Donald - Gem para auxiliar a resolver conflitos do GIT com o Vim'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/S6VDeOherlI/AAAAAAAAASQ/BtUYY7CwCkI/s72-c/donald.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-631269582403636882</id><published>2010-02-07T13:40:00.005-02:00</published><updated>2010-02-07T14:04:54.792-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails 3.0 Beta lançado!</title><content type='html'>Dia 05/02/2010 foi lançada a nova versão do Rails, 3.0, ainda beta.&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/S27j4QzCH4I/AAAAAAAAASI/TEFuItFWv5M/s1600-h/rails_logo.png"&gt;&lt;img style="cursor: pointer; width: 125px; height: 125px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/S27j4QzCH4I/AAAAAAAAASI/TEFuItFWv5M/s400/rails_logo.png" alt="" id="BLOGGER_PHOTO_ID_5435532356003962754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Se você deseja experimentar, instale dessa forma:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n&lt;br /&gt;sudo gem install rails --pre&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Fiz alguns testes agora a pouco e logo de cara já da pra perceber algumas das muitas diferenças. Algumas pequenas diferenças que que já dá pra se perceber só de gerar um scaffold:&lt;br /&gt;&lt;br /&gt;Comandos como &lt;span style="font-weight: bold;"&gt;script/generate&lt;/span&gt; e todos os outros que ficavam dentro da pasta script agora são executados a partir do comando &lt;span style="font-weight: bold;"&gt;rails&lt;/span&gt;. Por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rails g scaffold user name:string last_name:string&lt;br /&gt;rails server&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E o output desses comandos no terminal agora aparecem coloridos.&lt;br /&gt;&lt;br /&gt;As gems que o projeto utiliza agora são listadas num arquivo &lt;span style="font-weight: bold;"&gt;Gemfile&lt;/span&gt; na pasta raiz, não mais no environment.rb.&lt;br /&gt;&lt;br /&gt;Existe também um objeto da aplicação que é configurado em config/application.rb&lt;br /&gt;&lt;br /&gt;As mudanças são muitas, essas são só algumas pequenas que eu percebi ao gerar um scaffold. Mais detalhes você pode ver em:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://weblog.rubyonrails.org/2010/2/5/rails-3-0-beta-release"&gt;http://weblog.rubyonrails.org/2010/2/5/rails-3-0-beta-release&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ou no post traduzido pelo Akita:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.akitaonrails.com/2010/02/02/h2-anotacoes-de-lancamento-ruby-on-rails-3-0"&gt;http://www.akitaonrails.com/2010/02/02/h2-anotacoes-de-lancamento-ruby-on-rails-3-0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Aqui tem um screencast gratuito mostrando como converter uma aplicação do Rails 2.3.5 para 3.0:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.peepcode.com/tutorials/2010/live-coding-rails-3-upgrade"&gt;http://blog.peepcode.com/tutorials/2010/live-coding-rails-3-upgrade&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.akitaonrails.com/2010/02/02/h2-anotacoes-de-lancamento-ruby-on-rails-3-0"&gt;&lt;/a&gt;&lt;br /&gt;Acredito que a próxima etapa agora é migrar as gems e plugins das versões antigas para as novas, para aí sim podermos criar aplicações nessa nova versão.&lt;br /&gt;&lt;br /&gt;Foi criado também um site para listar as gems que já estão funcionando, você pode encontrar em:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://railsplugins.org/"&gt;http://railsplugins.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;É isso pessoal, até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-631269582403636882?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/631269582403636882/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=631269582403636882' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/631269582403636882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/631269582403636882'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/02/rails-30-beta-lancado.html' title='Rails 3.0 Beta lançado!'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_CGnpveaIy_M/S27j4QzCH4I/AAAAAAAAASI/TEFuItFWv5M/s72-c/rails_logo.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-7892752608255863005</id><published>2010-01-29T23:58:00.003-02:00</published><updated>2010-01-30T11:45:47.165-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='testes automatizados'/><title type='text'>Como executar o cucumber em português</title><content type='html'>Uma grande característica do &lt;a href="http://cukes.info/"&gt;cucumber&lt;/a&gt; é que você pode criar seus testes na sua lingua nativa, facilitando ainda mais o processo e a integração com o cliente.&lt;br /&gt;&lt;br /&gt;Recentemente o cucumber mudou a forma de se rodar as features em outra lingua, então vim aqui postar como ficou na nova versão (a partir da versão 0.5.0).&lt;br /&gt;&lt;br /&gt;Primeiramente, para listar os idiomas que o cucumber suporta, basta digitar o comando:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/290345.js?file=blog_02_example_01.sh"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Para nosso exemplo, vamos configurar ele em português.&lt;br /&gt;&lt;br /&gt;O cucumber trabalha com um arquivo chamado web_steps.rb (que antes se chamava webrat steps) que trás os steps mais utilizados já configurados. Você pode traduzir esse arquivo do modo que preferir para o português, ou utilizar a versão já traduzida pelo pessoal do cucumber, gerando-o com o comando que configura o cucumber no Rails dessa forma:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/290346.js?file=blog_02_example_02.sh"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Com isso você terá um arquivo chamado features/step_definitions/web_steps_pt-BR.rb&lt;br /&gt;&lt;br /&gt;Antes para executar as features em português você tinha que passar a linguagem para o cucumber através do parâmetro -language. Hoje esse parâmetro não existe mais, e para configurar sua feature em português basta adicionar a seguinte linha no começo do arquivo:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/290350.js?file=blog_02_example_03.feature"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;A partir daí você já pode criar suas features em português, um exemplo:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/290357.js?file=blog_02_example_04.feature"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Para listar as palavras chaves do cucumber em português você pode digitar:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/290359.js?file=blog_02_example_05.sh"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Bom, espero ter ajudado.&lt;br /&gt;&lt;br /&gt;Até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-7892752608255863005?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/7892752608255863005/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=7892752608255863005' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7892752608255863005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7892752608255863005'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/01/como-executar-o-cucumber-em-portugues.html' title='Como executar o cucumber em português'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8789437378777032248</id><published>2010-01-23T12:39:00.003-02:00</published><updated>2010-01-23T19:21:57.750-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='cache'/><title type='text'>Counter cache, Ruby on Rails</title><content type='html'>Um recurso interessante do Rails para otimização de desempenho é o counter_cache.&lt;br /&gt;&lt;br /&gt;Por exemplo, na página inicial de uma aplicação que estou trabalhando nós exibimos uma lista de eventos, e cada um desses eventos tem um ou mais orçamentos (Event has_many :budgets).&lt;br /&gt;&lt;br /&gt;Nós temos que exibir numa coluna a quantidade de orçamentos existentes desses eventos. Para isso uma solução seria fazer um SELECT COUNT para cada evento (listamos 30 eventos por página, então seriam 30 consultas) ou poderíamos fazer um SQL mais elaborado no começo para consultar já com os counters, o que poderia sair um pouco do padrão ou até complicar um pouco o código.&lt;br /&gt;&lt;br /&gt;Para solucionar meu problema eu acionei a opção de &lt;span style="font-weight: bold;"&gt;counter_cache&lt;/span&gt; no relacionamento &lt;span style="font-weight: bold;"&gt;belongs_to&lt;/span&gt; da minha classe &lt;span style="font-weight: bold;"&gt;Budget&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/284627.js?file=blog_01_example_01"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Sendo assim, o Active Record entende que existe um campo chamado &lt;span style="font-weight: bold;"&gt;budgets_count&lt;/span&gt; na tabela events, que ele atualiza toda vez que eu adiciono ou removo um orçamento de um evento.&lt;br /&gt;&lt;br /&gt;Na hora de listar os eventos na página inicial, ao invés de fazer um SELECT para cada um dos eventos, eu vou direto nesse contador gerado pelo Active Record.&lt;br /&gt;&lt;br /&gt;O desempenho fica muito melhor porque eu visualizo muito mais a página inicial do que cadastro orçamentos, então vale mais a pena deixar o Rails atualizar esse número na hora do cadastro, do que fazer essa conta toda vez que eu exibo. Além disso, para o Rails atualizar esse contador não demanda muito processamento, uma vez que ele não calcula efetivamente quantos itens tem toda hora que eu salvo, e sim incrementa ou decrementa o contador a partir do número atual.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Como fazer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Vou explicar passo a passo como configurar. Vamos criar um exemplo aonde eu tenho a classe &lt;span style="font-weight: bold;"&gt;Album&lt;/span&gt; e a classe &lt;span style="font-weight: bold;"&gt;Picture&lt;/span&gt;. E um album tem muitas pictures.&lt;br /&gt;&lt;br /&gt;Primeiramente, vamos configurar nossa classe &lt;span style="font-weight: bold;"&gt;Picture&lt;/span&gt; para dizer que o relacionamento &lt;span style="font-weight: bold;"&gt;belongs_to&lt;/span&gt; dela em relação a &lt;span style="font-weight: bold;"&gt;Album&lt;/span&gt; deve ter &lt;span style="font-weight: bold;"&gt;counter_cache&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;O model de &lt;span style="font-weight: bold;"&gt;Picture&lt;/span&gt; ficaria assim:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/284629.js?file=blog_01_example_02.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;E o model Album:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/284630.js?file=blog_01_example_03.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Quando colocamos a opção &lt;span style="font-weight: bold;"&gt;counter_cache&lt;/span&gt; como true, o Active Record entende que na tabela albums existirá uma coluna com o nome &lt;span style="font-weight: bold;"&gt;pictures_count&lt;/span&gt; (nome da tabela + '_count'). Se você quiser utilizar um campo com um nome diferente, basta informar no lugar do true, exemplo: &lt;span style="font-weight: bold;"&gt;:counter_cache =&gt; 'my_custom_counter'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora temos de criar o campo na tabela &lt;span style="font-weight: bold;"&gt;albums&lt;/span&gt;. Vamos fazer uma migração para adicionar esse campo (caso o modelo já exista):&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/284633.js?file=blog_01_example_04.sh"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Com o comando acima a migração será gerada quase pronta, você só precisará adicionar &lt;span style="font-weight: bold;"&gt;:default =&gt; 0&lt;/span&gt; no campo &lt;span style="font-weight: bold;"&gt;pictures_count&lt;/span&gt;, deve ficar assim:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/284634.js?file=blog_01_example_05.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos testar para ver se funciona. Segue abaixo alguns comandos que executei no terminal para criar um álbum com duas fotografias:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/284636.js?file=blog_01_example_06.sh"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos analisar o SQL gerado para esses comandos:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/284637.js?file=blog_01_example_07.sql"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Ele consultou o banco para buscar as colunas de Album e Picture, depois fez os INSERTS e UPDATES para atualizar os contadores. Mas no final, quando solicitei solicitei a quantidade de fotografias do último álbum, ele apenas buscou o álbum mas não precisou fazer um SELECT COUNT para saber quantas tinhas, ele utilizou o cache.&lt;br /&gt;&lt;br /&gt;Se o cache não existisse, você veria também o SQL abaixo:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/284638.js?file=blog_01_example_08.sql"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Pode parecer pouco, mas numa página que é muito requisitada, e que exibe muitos registros, pode fazer diferença. Principalmente em épocas de servidor congestionado.&lt;br /&gt;&lt;br /&gt;Existem algumas outras formas interessantes de cache que o Rails oferece, como o cache de página, de action, de fragmento, de SQL, entre outros.&lt;br /&gt;&lt;br /&gt;Você pode ler a respeito deles em:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://guides.rubyonrails.org/caching_with_rails.html"&gt;http://guides.rubyonrails.org/caching_with_rails.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Talvez mais pra frente eu fale de outros caches aqui no Blog.&lt;br /&gt;&lt;br /&gt;Bom, é isso pessoal, espero ter ajudado. Qualquer dúvida ou opiniões podem postar comentários ou entrar em contato comigo através de e-mail, &lt;a href="http://twitter.com/grasselli"&gt;twitter&lt;/a&gt;, gtalk, etc.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8789437378777032248?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8789437378777032248/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8789437378777032248' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8789437378777032248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8789437378777032248'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2010/01/counter-cache-ruby-on-rails.html' title='Counter cache, Ruby on Rails'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-3953422728188788634</id><published>2009-12-06T19:13:00.010-02:00</published><updated>2009-12-06T20:15:27.246-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='orientação a objetos'/><title type='text'>Associações polimórficas com Ruby on Rails</title><content type='html'>Hoje vou falar de um recurso que utilizei bastante nos últimos dias nos projetos que estou envolvido e acredito que seja útil para muitos.&lt;br /&gt;&lt;br /&gt;O polimorfismo é uma características que existe em muitas linguagens orientadas a objetos, quando falamos de uma associação polimórfica, estamos dizendo que um objeto tem um outro objeto (ou mais), e esse outro objeto pode ser de várias formas (classes) diferentes.&lt;br /&gt;&lt;br /&gt;Por exemplo:&lt;br /&gt;&lt;br /&gt;Um objeto do tipo &lt;span style="font-weight: bold;"&gt;Tabuleiro&lt;/span&gt; (xadrez) tem muitas &lt;span style="font-weight: bold;"&gt;Peças&lt;/span&gt;, e essas peças podem ser de várias classes diferentes (&lt;span style="font-weight: bold;"&gt;Peão&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;Bispo&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;Torre&lt;/span&gt;, etc...).&lt;br /&gt;&lt;br /&gt;Um exemplo na prática, digamos que existe a classe &lt;span style="font-weight: bold;"&gt;BankAccount&lt;/span&gt; (conta corrente) em sua aplicação Rails.&lt;br /&gt;&lt;br /&gt;Essa &lt;span style="font-weight: bold;"&gt;BankAccount&lt;/span&gt; pertence a alguém, mas esse alguém pode ser um fornecedor (&lt;span style="font-weight: bold;"&gt;Supplier&lt;/span&gt;), um cliente (&lt;span style="font-weight: bold;"&gt;Customer&lt;/span&gt;) ou até mesmo um usuário (&lt;span style="font-weight: bold;"&gt;User&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Para lidarmos com esse tipo de situação no Ruby e persistir essas informações no banco de dados em uma aplicação Rails, podemos fazer da seguinte forma:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Primeiro passo: Definir um nome para essa associação&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Nossa conta corrente pertence a qualquer objeto apto a ter uma conta corrente, vou chamar esse tipo de objeto de "accountable".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Segundo passo: Criar as colunas no banco de dados&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Temos que criar duas colunas no banco de dados, uma que registrará o tipo do objeto (nome da classe) e outra o id do objeto.&lt;br /&gt;&lt;br /&gt;Para criar essas colunas em uma migração, basta escrevermos assim:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/Sxwj_WGBWRI/AAAAAAAAARc/sx4tqqoUqQU/s1600-h/migration.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 292px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/Sxwj_WGBWRI/AAAAAAAAARc/sx4tqqoUqQU/s400/migration.png" alt="" id="BLOGGER_PHOTO_ID_5412240423362058514" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Como visto na linha 9, a síntaxe é:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;t.references :accountable, :polymorphic =&gt; true&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ou você pode criar manualmente duas colunas, uma com o nome da associação mais "_id" do tipo integer, e outra com o nome + "_type" do tipo string, como no exemplo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SxwlWVUxSRI/AAAAAAAAARk/UJGkbvXjFvQ/s1600-h/migration2.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 178px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SxwlWVUxSRI/AAAAAAAAARk/UJGkbvXjFvQ/s400/migration2.png" alt="" id="BLOGGER_PHOTO_ID_5412241917804103954" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Terceiro passo: configurar a classe BankAccount&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para definir a associação na classe BankAccount, fazemos assim:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SxwpyatMTnI/AAAAAAAAAR0/OBR8F4JYBsw/s1600-h/bank_account.png"&gt;&lt;img style="cursor: pointer; width: 347px; height: 52px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SxwpyatMTnI/AAAAAAAAAR0/OBR8F4JYBsw/s400/bank_account.png" alt="" id="BLOGGER_PHOTO_ID_5412246798331563634" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Como visto na imagem:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;belongs_to :accountable, :polymorphic =&gt; true&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Quarto passo: configurar as classes que possuirão contas corrente&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para fazer isso, basta definirmos a associação nas classes que desejamos que possuam contas corrente, por exemplo, na classe Supplier:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/Sxwms677zMI/AAAAAAAAARs/RQ3i9bCDvs0/s1600-h/supplier.png"&gt;&lt;img style="cursor: pointer; width: 339px; height: 53px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/Sxwms677zMI/AAAAAAAAARs/RQ3i9bCDvs0/s400/supplier.png" alt="" id="BLOGGER_PHOTO_ID_5412243405369232578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Como mostrado na imagem, para definir a associação:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;has_many :bank_accounts, :as =&gt; :accountable&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Último passo: Utilizar onde for preciso&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Uma vez configurada, para utilizar é muito simples, por exemplo, para dizer a uma conta que ela pertence a um usuário:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;account.accountable = user&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;(supondo que a variável user está carregada com um objeto do tipo User)&lt;br /&gt;&lt;br /&gt;Digamos que a conta pertence a um Supplier, e você deseja ver a razão social desse fornecedor:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;account.accountable.corporate_name&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Você pode também, a partir do objeto user ou qualquer outro objeto que possua a associação, recuperar um array de contas a partir de:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;user.bank_accounts&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Concluindo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Você pode estudar mais a respeito desse tipo de associação no &lt;a href="http://guias.rubyonrails.pro.br/association_basics.html#associaes-polimrficas"&gt;Rails Guide.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Espero ter ajudado, qualquer dúvida pode postar um comentário ou entrar em contato via &lt;a href="http://twitter.com/grasselli"&gt;twitter&lt;/a&gt;, gtalk, e-mail, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-3953422728188788634?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/3953422728188788634/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=3953422728188788634' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3953422728188788634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3953422728188788634'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/12/associacoes-polimorficas-com-ruby-on.html' title='Associações polimórficas com Ruby on Rails'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/Sxwj_WGBWRI/AAAAAAAAARc/sx4tqqoUqQU/s72-c/migration.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-102045500199895378</id><published>2009-11-22T18:59:00.003-02:00</published><updated>2009-11-22T19:11:53.521-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><title type='text'>Navegadores que acessam o blog</title><content type='html'>Acredito que esse tipo de informação é importante para nós que desenvolvemos para a internet, seria interessante se todos compartilhássemos esse tipo de estatísticas.&lt;br /&gt;&lt;br /&gt;O gráfico abaixo mostra as visitas da última semana do blog por navegadores (clique na imagem para ampliá-la).&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SwmnQg28HUI/AAAAAAAAARU/RuVVmYuBC5s/s1600/navegadores.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 136px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SwmnQg28HUI/AAAAAAAAARU/RuVVmYuBC5s/s400/navegadores.png" alt="" id="BLOGGER_PHOTO_ID_5407036729775103298" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Para minha felicidade, o blog é mais acessado por usuários com Firefox (66,09%), mas isso só é possível porque o blog tem um público específico, na sua grande maioria formado por desenvolvedores web, que estão mais do que cansados de saber que Internet Explorer é um lixo.&lt;br /&gt;&lt;br /&gt;Em sites com público variado que tenho acesso às estatísticas, a maioria ainda usa Internet Explorer, e o que é pior, muitas vezes na versão 6.&lt;br /&gt;&lt;br /&gt;Um dia ainda conseguiremos inverter essa estatística, para o nosso bem (desenvolvedores) e para um melhor proveito da internet pelos usuários, e com mais segurança.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-102045500199895378?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/102045500199895378/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=102045500199895378' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/102045500199895378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/102045500199895378'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/11/navegadores-que-acessam-o-blog.html' title='Navegadores que acessam o blog'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/SwmnQg28HUI/AAAAAAAAARU/RuVVmYuBC5s/s72-c/navegadores.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8902630398061420881</id><published>2009-11-05T21:44:00.004-02:00</published><updated>2009-11-05T22:46:45.179-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><title type='text'>Método toggle() do Jquery com problemas no IE8</title><content type='html'>Esses dias tive que usar algumas soluções em javascript, mais especificamente Jquery,  pra atender a uma necessidade em nosso projeto.&lt;br /&gt;&lt;br /&gt;Depois da página feita fui testar em outros navegadores (eu crio primeiro no Firefox) e uma funcionalidade simples, que é o método toggle() do Jquery (utilizado pra esconder / exibir um elemento), havia parado de funcionar somente no IE8, até no IE6 funcionava, mas no 8 não.&lt;br /&gt;&lt;br /&gt;O mais estranho era que a versão anterior dessa página utilizava o toggle e ele funcionava no IE8, por que então parou de funcionar?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;O problema.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Depois de analisar bem o código percebi que a única diferença era que eu tinha trocado o elemento em qual eu invocava o toggle. Antes era uma DIV e depois eu troquei para uma TR.&lt;br /&gt;&lt;br /&gt;Foi então que eu descobri, através desse tópico aqui (&lt;a href="http://stackoverflow.com/questions/975153/jquery-toggle-not-working-with-trs-in-ie"&gt;http://stackoverflow.com/questions/975153/jquery-toggle-not-working-with-trs-in-ie&lt;/a&gt;) que o toggle do Jquery não funciona bem no IE8. Ele esconde a primeira vez, mas após isso ele não consegue mais exibir. No meu caso como já vinha escondido quando a página era carregada, ele nunca aparecia.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A solução.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Parece que o problema acontece devido a forma que o Jquery valida se o TR está escondido ou não, que retorna sempre true, falando que ele está visível.&lt;br /&gt;&lt;br /&gt;Para solucionar o problema eu escrevi um método (ou função), que faz praticamente a mesma coisa que o toggle, só que verificando de outra forma, ficou assim (na verdade a ideia do método foi do Brian Bolton, naquele tópico que mencionei, eu apenas adaptei para funcionar com id's, que ficava melhor para o que eu precisava):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SvNqJTmHHKI/AAAAAAAAARM/jNpjLUjQ5xg/s1600-h/Captura+de+tela+2009-11-05+%C3%A0s+22.12.46.png"&gt;&lt;img style="cursor: pointer; width: 259px; height: 178px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SvNqJTmHHKI/AAAAAAAAARM/jNpjLUjQ5xg/s400/Captura+de+tela+2009-11-05+%C3%A0s+22.12.46.png" alt="" id="BLOGGER_PHOTO_ID_5400777086258846882" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Utilizando essa função funcionou bem em todos os navegadores que testei.&lt;br /&gt;&lt;br /&gt;Na verdade, se você habilitar a opção do IE8 de suporte a navegadores antigos funciona com o toggle simples, mas não podemos exigir que nossos clientes usem.&lt;br /&gt;&lt;br /&gt;Enfim, mais uma vez isso só aumentou meu desejo de que o Internet Explorer sumisse de vez da internet, mas...&lt;br /&gt;&lt;br /&gt;Espero que o post ajude quem estiver passando pelo mesmo problema.&lt;br /&gt;&lt;br /&gt;Abraços.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8902630398061420881?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8902630398061420881/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8902630398061420881' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8902630398061420881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8902630398061420881'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/11/metodo-toggle-do-jquery-com-problemas.html' title='Método toggle() do Jquery com problemas no IE8'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/SvNqJTmHHKI/AAAAAAAAARM/jNpjLUjQ5xg/s72-c/Captura+de+tela+2009-11-05+%C3%A0s+22.12.46.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6607333753927872079</id><published>2009-11-04T23:17:00.003-02:00</published><updated>2009-11-04T23:38:40.837-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><title type='text'>Claro 3g no Mac OS X</title><content type='html'>Há um ou dois meses atrás eu tomei coragem e comprei meu primeiro Mac, um Macbook branco, infelizmente ainda no formato antigo, o novo saiu um mês depois da compra, mais barato do que eu paguei. Mas tudo bem, detalhes a parte, se você está na mesma dúvida que eu tinha se vale ou não a pena comprar um Mac, aceite minha dica, vale sim muito a pena, eu deveria ter comprado antes.&lt;br /&gt;&lt;br /&gt;No laptop antigo eu usava Claro 3g, com o modem Huawei E226, para quando eu estava em algum lugar que não tinha wireless (se você está procurando uma operadora de internet móvel, não escolha a Claro. A internet vai ficar super lenta após alguns meses e você nunca vai conseguir ser atendido por eles no telefone).&lt;br /&gt;&lt;br /&gt;Enfim, como ainda tenho mais alguns meses pra pagar antes de poder encerrar o contrato, eu queria que o Claro 3g funcionasse no meu Mac.&lt;br /&gt;&lt;br /&gt;Procurando em alguns blogs li que a Claro era a única até o momento que oferecia suporte ao Mac OS X (apesar deles nunca atenderem minhas ligações para prestarem esse suporte), e encontrei um monte de programas, que supostamente eram os drivers, mas nenhum funcionou.&lt;br /&gt;&lt;br /&gt;Hoje resolvi tentar de novo e dessa vez eu consegui, por isso vim aqui dizer para você como.&lt;br /&gt;&lt;br /&gt;No link abaixo eu consegui fazer o download do driver que funciona:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.evandavey.com/2008/02/how-to-connect-huawei-e220-usb-modem.html"&gt;http://blog.evandavey.com/2008/02/how-to-connect-huawei-e220-usb-modem.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Detalhe que dentro do zip possui dois arquivos, o que você deve usar é o segundo, com o nome:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;HuaweiDataCardDriver(2.6)-intel&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para instalar basta dar dois cliques e ficar apertando em "próximo".&lt;br /&gt;&lt;br /&gt;Depois de instalar conecte seu modem. No meu caso ele mesmo disse que havia uma nova conexão e pediu para configurar, mas se isso não aconteceu para você, entre em:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Preferências do sistema -&gt; Rede&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Se o dispositivo HUAWEI mobile não apareceu para você na lista a esquerda, clique no botão com um sinal de + (mais) la em baixo para adicionar, selecione a interface Huawei mobile e de um nome para ela.&lt;br /&gt;&lt;br /&gt;Após adicionado basta configurar e por para funcionar, os dados para configuração são:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Configuração: Padrão&lt;br /&gt;Telefone: *99***1#&lt;br /&gt;Nome da conta: claro&lt;br /&gt;Senha: claro&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Informações retiradas de:&lt;br /&gt;&lt;a href="http://macmagazine.uol.com.br/2008/01/18/dica-como-configurar-o-modem-huawei-e226-da-claro-3g-no-leopard"&gt;http://macmagazine.uol.com.br/2008/01/18/dica-como-configurar-o-modem-huawei-e226-da-claro-3g-no-leopard&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Você pode também selecionar a opção: "Mostrar o estado do modem na barra de menus".&lt;br /&gt;&lt;br /&gt;Com isso já deve começar a funcionar!&lt;br /&gt;&lt;br /&gt;Espero que a dica ajude, no meu caso funcionou no Mac OS X Snow Leopard também.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post.&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6607333753927872079?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6607333753927872079/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6607333753927872079' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6607333753927872079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6607333753927872079'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/11/claro-3g-no-mac-os-x.html' title='Claro 3g no Mac OS X'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-745192891224905175</id><published>2009-11-01T21:32:00.003-02:00</published><updated>2009-11-01T21:38:27.004-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evento'/><title type='text'>Dev in Sampa</title><content type='html'>Pessoal, post rápido para ajudar a divulgar uma nova iniciativa de evento da comunidade de desenvolvedores de são paulo, o Dev in Sampa.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.devinsampa.com.br/"&gt;&lt;img src="http://www.devinsampa.com.br/images/dev-in-sampa.gif" alt="Dev In Sampa" height="90" width="310" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Informações:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;O que é?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;É o primeiro encontro de desenvolvedores de software em São Paulo, onde  serão ministradas    palestras voltados a desenvolvimento, arquitetura e engenharia de software.  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Quando?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Será realizado dia 28/11 (sábado), das 9:00 às 18:00.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Onde?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Editora Abril S/A - Auditório  &lt;address&gt;Av. das Nações Unidas, 7221 - Alto de Pinheiros - São Paulo, SP, 05425-070&lt;/address&gt;&lt;br /&gt;Para mais informações visitem: &lt;a href="http://www.devinsampa.com.br"&gt;http://www.devinsampa.com.br&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Eu vou!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-745192891224905175?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/745192891224905175/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=745192891224905175' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/745192891224905175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/745192891224905175'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/11/dev-in-sampa.html' title='Dev in Sampa'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6957695105354765525</id><published>2009-10-11T16:21:00.003-03:00</published><updated>2009-10-11T16:52:21.098-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='editores de texto'/><title type='text'>Trabalhando com abas no VIM</title><content type='html'>Recentemente comecei a tentar usar o Textmate, mas ainda não consegui abandonar o Vim. Uma coisa que vi no Textmate que eu queria que tivesse no Vim são as abas.&lt;br /&gt;&lt;br /&gt;Mas o que eu descobri esses dias é que o Vim trabalha com abas também, a partir da versão 7 (eu não sabia disso).&lt;br /&gt;&lt;br /&gt;Se você também não sabia, seguem alguns comandos para trabalhar com as abas:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:tabnew&lt;/span&gt;&lt;br /&gt;Abre uma nova aba&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:tabn número&lt;/span&gt;&lt;br /&gt;Navega entre as abas, exemplo:&lt;br /&gt;tab 2 (vai para a aba número 2)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:tabnext&lt;/span&gt;&lt;br /&gt;Vai para a próxima aba&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:tabprev&lt;/span&gt;&lt;br /&gt;Vai para a aba anterior&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:tabfirst&lt;/span&gt;&lt;br /&gt;Vai para a primeira aba&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:tablast&lt;/span&gt;&lt;br /&gt;Vai para a última aba&lt;br /&gt;&lt;br /&gt;E se você usa &lt;span style="font-weight: bold;"&gt;rails-vim&lt;/span&gt; e está acostumado com comandos como &lt;span style="font-weight: bold;"&gt;:RSmodel&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;RVcontroller&lt;/span&gt;, etc, você pode utilizar também a versão desses comandos com &lt;span style="font-weight: bold;"&gt;T&lt;/span&gt;, exemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:RTmodel&lt;/span&gt;&lt;br /&gt;Abre um model numa nova aba&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:RTview&lt;/span&gt;&lt;br /&gt;Abre uma view numa nova aba&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:RTcontroller&lt;/span&gt;&lt;br /&gt;Abre um controller numa nova aba&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;:AT&lt;/span&gt;&lt;br /&gt;Abre o teste numa nova aba&lt;br /&gt;&lt;br /&gt;Uma coisa que aconteceu comigo usando abas no gvim + Ubuntu foi que quando eu abri as abas (com o gvim maximizado) a linha de comando do vim sumiu. Se isso aconteceu com você também basta restaurar e maximizar o vim novamente.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6957695105354765525?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6957695105354765525/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6957695105354765525' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6957695105354765525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6957695105354765525'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/10/trabalhando-com-abas-no-vim.html' title='Trabalhando com abas no VIM'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2730404187032627056</id><published>2009-10-10T19:07:00.009-03:00</published><updated>2009-10-10T19:52:46.417-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='rake'/><title type='text'>Criando rake tasks</title><content type='html'>Um ótimo jeito de criar um script Ruby para sua aplicação Rails, principalmente se ele precisar ter o ambiente do Rails carregado, é através de rake tasks.&lt;br /&gt;&lt;br /&gt;Quando eu ouvia falar de criar rake tasks eu achava que devia ser algo complexo, mas esses dias precisei criar um script Ruby para popular o banco de minha aplicação e o &lt;a href="http://cassiomarques.wordpress.com/"&gt;Cassio Marques&lt;/a&gt; me falou pra dar uma olhada nesse tipo de arquivo, me impressionei com o quão simples é criar uma.&lt;br /&gt;&lt;br /&gt;Para criar uma rake task crie um arquivo com a extensão .rake dentro do diretório &lt;span style="font-weight: bold;"&gt;lib/tasks&lt;/span&gt; de sua aplicação. Exemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;lib/tasks/example.rake&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Dentro do arquivo abra um bloco como o do exemplo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/StEIml9XNhI/AAAAAAAAAQk/6CzUr8r8wTs/s1600-h/Captura+de+tela+2009-10-10+%C3%A0s+19.19.23.png"&gt;&lt;img style="cursor: pointer; width: 193px; height: 58px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/StEIml9XNhI/AAAAAAAAAQk/6CzUr8r8wTs/s400/Captura+de+tela+2009-10-10+%C3%A0s+19.19.23.png" alt="" id="BLOGGER_PHOTO_ID_5391099688056731154" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dentro desse bloco você pode escrever script Ruby, por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/StEJWN4fEkI/AAAAAAAAAQs/VuKleXqik9M/s1600-h/Captura+de+tela+2009-10-10+%C3%A0s+19.22.42.png"&gt;&lt;img style="cursor: pointer; width: 188px; height: 90px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/StEJWN4fEkI/AAAAAAAAAQs/VuKleXqik9M/s400/Captura+de+tela+2009-10-10+%C3%A0s+19.22.42.png" alt="" id="BLOGGER_PHOTO_ID_5391100506227544642" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A partir daí você já pode executar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rake my_new_rake_task&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;O resultado será:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rake my_new_rake_task&lt;br /&gt;(in /Users/bruno/projetos/scafold)&lt;br /&gt;Hello&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Você pode também adicionar uma descrição para ela, assim ela aparecerá na lista de taks do rake:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/StEKzVIXqrI/AAAAAAAAAQ0/FHzOHTxRTpI/s1600-h/Captura+de+tela+2009-10-10+%C3%A0s+19.29.07.png"&gt;&lt;img style="cursor: pointer; width: 188px; height: 106px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/StEKzVIXqrI/AAAAAAAAAQ0/FHzOHTxRTpI/s400/Captura+de+tela+2009-10-10+%C3%A0s+19.29.07.png" alt="" id="BLOGGER_PHOTO_ID_5391102105901050546" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para ver a sua task na lista execute o comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rake -T&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ou, para achar ela de uma forma mais fácil:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rake -T | grep new&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Como resultado, dentre a lista que aparecer você encontrará:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rake my_new_rake_task                     # Just an example&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Caso você precise do ambiente Rails carregado para executar o seu script, na hora de abrir o bloco faça da seguinte forma:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;task :name =&gt; :environment do&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Como no exemplo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/StENi1fGfsI/AAAAAAAAAQ8/7pTs0pVs3nA/s1600-h/Captura+de+tela+2009-10-10+%C3%A0s+19.40.38.png"&gt;&lt;img style="cursor: pointer; width: 307px; height: 185px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/StENi1fGfsI/AAAAAAAAAQ8/7pTs0pVs3nA/s400/Captura+de+tela+2009-10-10+%C3%A0s+19.40.38.png" alt="" id="BLOGGER_PHOTO_ID_5391105121063435970" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Você pode criar mais de uma task por arquivo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/StEOamf067I/AAAAAAAAARE/cREJnweynb8/s1600-h/Captura+de+tela+2009-10-10+%C3%A0s+19.43.46.png"&gt;&lt;img style="cursor: pointer; width: 307px; height: 266px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/StEOamf067I/AAAAAAAAARE/cREJnweynb8/s400/Captura+de+tela+2009-10-10+%C3%A0s+19.43.46.png" alt="" id="BLOGGER_PHOTO_ID_5391106079112620978" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Bom é isso pessoal, a partir daí basta utilizar o poder do Ruby e do Rails para criar as mais diversas tarefas.&lt;br /&gt;&lt;br /&gt;Espero que o post ajude e até o próximo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2730404187032627056?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2730404187032627056/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2730404187032627056' title='5 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2730404187032627056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2730404187032627056'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/10/criando-rake-tasks.html' title='Criando rake tasks'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/StEIml9XNhI/AAAAAAAAAQk/6CzUr8r8wTs/s72-c/Captura+de+tela+2009-10-10+%C3%A0s+19.19.23.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8700876054761432926</id><published>2009-10-02T21:49:00.005-03:00</published><updated>2009-10-02T22:38:27.974-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Problema ao renderizar view no formato XLS no Internet Explorer</title><content type='html'>Saudações pessoal,&lt;br /&gt;&lt;br /&gt;Já faz um tempo que eu não posto nada, o último mês foi bem corrido, comecei em um novo emprego (dessa vez com Ruby on Rails), além das provas na faculdade, entre outros. Mas estou cheio de assuntos novos para tratar no blog.&lt;br /&gt;&lt;br /&gt;Antes de mais nada queria parabenizar o pessoal do &lt;a href="http://www.guru-sp.org/"&gt;GURU-SP&lt;/a&gt; que fez mais um excelente evento no final de semana passado, cheio de gente e com o conteúdo muito interessante (testes). Se você ainda não participa do grupo não deixe de dar uma olhada.&lt;br /&gt;&lt;br /&gt;Hoje gostaria de falar pra vocês a respeito de um problema muito estranho que tive para renderizar arquivos xls (Excel) no serviço.&lt;br /&gt;&lt;br /&gt;Fizemos uma reelaboração do módulo de relatórios de nossa aplicação recentemente e nesse novo modelo é possível visualizar um relatório nos formatos: html, pdf e xls.&lt;br /&gt;&lt;br /&gt;Testamos no nosso ambiente de desenvolvimento (Linux ou Mac OS X com Firefox) e tudo parecia correr tudo bem.&lt;br /&gt;&lt;br /&gt;Para fazer com que sua aplicação renderize views no formato do Excel é bem simples, basta adicionar no arquivo &lt;span style="font-weight: bold;"&gt;config/initializers/mime_types.rb&lt;/span&gt; a linha:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Mime::Type.register "application/vnd.ms-excel", :xls&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E na hora de renderizar no controller:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SsakXNWCHeI/AAAAAAAAAQU/LN1g5t9daGw/s1600-h/Captura+de+tela+2009-10-02+%C3%A0s+22.09.03.png"&gt;&lt;img style="cursor: pointer; width: 175px; height: 82px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SsakXNWCHeI/AAAAAAAAAQU/LN1g5t9daGw/s400/Captura+de+tela+2009-10-02+%C3%A0s+22.09.03.png" alt="" id="BLOGGER_PHOTO_ID_5388174722821397986" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Aí basta criar o arquivo com o nome no formato:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;nome_da_action.xls.rb&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Nesse arquivo você pode escrever uma tabela no formato html, ou até mesmo criar um arquivo no formato xml, como o Ary Djmal mostra nesse post:&lt;br /&gt;&lt;a href="http://arydjmal.com/2008/6/8/export-to-excel-in-rails-2"&gt;&lt;br /&gt;http://arydjmal.com/2008/6/8/export-to-excel-in-rails-2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hoje, com a aplicação em produção, descobrimos que o Internet Explorer apresenta um comportamento completamente estranho em relação a esse tipo de tratamento.&lt;br /&gt;&lt;br /&gt;Quando clicavam no link para exibir a página no formato html, por algum motivo estranho o IE tentava sempre renderizar o formato xls ao invés do html.&lt;br /&gt;&lt;br /&gt;Para resolver esse problema utilizamos a solução sugerida pelo Ary Djmal no &lt;a href="http://arydjmal.com/2008/6/8/export-to-excel-in-rails-2"&gt;link&lt;/a&gt; que mencionei acima (thank you man), que foi adicionar a seguinte condição na hora de renderizar:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/Ssanctf4ExI/AAAAAAAAAQc/6ahDG1Mz5UI/s1600-h/Captura+de+tela+2009-10-02+%C3%A0s+22.21.52.png"&gt;&lt;img style="cursor: pointer; width: 301px; height: 72px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/Ssanctf4ExI/AAAAAAAAAQc/6ahDG1Mz5UI/s400/Captura+de+tela+2009-10-02+%C3%A0s+22.21.52.png" alt="" id="BLOGGER_PHOTO_ID_5388178115886846738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dessa forma funciona no IE e continua funcionando nos outros navegadores.&lt;br /&gt;&lt;br /&gt;Como a informação foi muito útil para mim, resolvi passar ela adiante pra quem passar pelo mesmo problema.&lt;br /&gt;&lt;br /&gt;Não sei por que ele acontece, se alguêm souber estou muito interessado em saber.&lt;br /&gt;&lt;br /&gt;No mais, isso só aumenta meu desprezo pelo Internet Explorer.&lt;br /&gt;&lt;br /&gt;Espero que o post ajude, tenho mais alguns assuntos interessantes que gostaria de escrever mas exigem um pouco mais de tempo, vou tentar escrever esse final de semana.&lt;br /&gt;&lt;br /&gt;Abraços.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8700876054761432926?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8700876054761432926/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8700876054761432926' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8700876054761432926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8700876054761432926'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/10/problema-ao-renderizar-view-no-formato.html' title='Problema ao renderizar view no formato XLS no Internet Explorer'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_CGnpveaIy_M/SsakXNWCHeI/AAAAAAAAAQU/LN1g5t9daGw/s72-c/Captura+de+tela+2009-10-02+%C3%A0s+22.09.03.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6989472511328039238</id><published>2009-08-09T18:10:00.003-03:00</published><updated>2009-08-09T18:26:09.366-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Saber, dentro de um helper, o nome da view que o invocou</title><content type='html'>Esses dias eu estava querendo criar um helper para me ajudar com o I18n (Internationalization) da minha aplicação.&lt;br /&gt;&lt;br /&gt;O problema é que dentro desse helper, eu precisava saber o nome da view que o invocou.&lt;br /&gt;&lt;br /&gt;Geralmente nós usamos &lt;span style="font-weight: bold;"&gt;params[:controller]&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;params[:action]&lt;/span&gt; para saber o nome do controller e da action, respectivamente. Para saber o nome da view, as vezes é usado a constante &lt;span style="font-weight: bold;"&gt;__FILE__&lt;/span&gt;, mas nesse caso ela não ajuda porque se você usá-la dentro de um helper ela te retornará o nome do arquivo do helper, e não da view que o invocou.&lt;br /&gt;&lt;br /&gt;Postei a pergunta no grupo da &lt;a href="http://groups.google.com.br/group/rails-br"&gt;rails-br&lt;/a&gt; e o &lt;a href="http://twitter.com/rafaelrosafu"&gt;Rafael Rosa&lt;/a&gt; descobriu a solução pra mim (através desse &lt;a href="http://stackoverflow.com/questions/333876/current-view-file-in-rails-helper-method"&gt;link&lt;/a&gt;). Para conseguir o nome da view, você pode usar um desses métodos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;@template.template.relative_path&lt;br /&gt;@template.template.base_path&lt;br /&gt;@template.template.filename&lt;br /&gt;@template.template.path_without_format_and_extension&lt;br /&gt;@template.template.path_without_extension&lt;br /&gt;@template.template.source&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Acredito que os nomes são auto explicativos.&lt;br /&gt;&lt;br /&gt;Como a dica foi útil para mim, resolvi publicar aqui para caso mais alguém estiver com esse problema.&lt;br /&gt;&lt;br /&gt;Abraços, e até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6989472511328039238?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6989472511328039238/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6989472511328039238' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6989472511328039238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6989472511328039238'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/08/saber-dentro-de-um-helper-o-nome-da.html' title='Saber, dentro de um helper, o nome da view que o invocou'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-1070072746739620477</id><published>2009-08-08T14:52:00.002-03:00</published><updated>2009-08-08T15:08:25.680-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='editores de texto'/><title type='text'>Indentar linhas no VIM</title><content type='html'>Há alguns meses escolhi o vim como meu editor de textos para trabalhar com Rails. Ainda sou um usuário novo de vim, e sempre acabo aprendendo um ou outro comando novo com ele.&lt;br /&gt;&lt;br /&gt;Nunca soube como fazer para indentar as linhas nele, aí hoje tomei vergonha na cara e fui procurar no google um comando para isso. O comando é muito simples, e também muito útil.&lt;br /&gt;&lt;br /&gt;Para indentar uma linha, basta posicionar o cursor sobre a linha desejada, em modo de comando (ESC) digitar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;==&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Se você quer, por exemplo, indentar as próximas 5 linhas, pode usar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;5=&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ou o número de linhas que desejar.&lt;br /&gt;&lt;br /&gt;Com == e 5= ele indenta de acordo com o código e a indentação anterior.&lt;br /&gt;&lt;br /&gt;Se você deseja simplesmente indentar a linha atual pra frente ou para trás, independente de código, pode usar também:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&gt;&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;e&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;&lt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Bom é isso pessoal, espero que a dica ajude.&lt;br /&gt;&lt;br /&gt;Pretendo fazer um post depois sobre os comandos que mais utilizo no vim. Se você indenta no vim de algum outra forma, ou se tem algum comando que você usa com frequência e acha útil fique a vontade para postar um comentário e contribuir com o post.&lt;br /&gt;&lt;br /&gt;Abraços!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-1070072746739620477?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/1070072746739620477/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=1070072746739620477' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1070072746739620477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1070072746739620477'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/08/indentar-linhas-no-vim.html' title='Indentar linhas no VIM'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-7380175931046547092</id><published>2009-08-05T22:03:00.008-03:00</published><updated>2009-08-09T18:27:00.528-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails na prática'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='dry'/><title type='text'>Enviar parâmetros para um partial</title><content type='html'>Essa é uma dica simples, mas que tem sua utilidade.&lt;br /&gt;&lt;br /&gt;O método &lt;span style="font-weight: bold;"&gt;render :partial&lt;/span&gt; recebe um hash com o nome &lt;span style="font-weight: bold;"&gt;locals&lt;/span&gt;. O conteúdo desse hash é disponibilizado dentro do partial como variáveis locais.&lt;br /&gt;&lt;br /&gt;Por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;%= render :partial =&gt; 'example', :locals =&gt; {:name =&gt; 'Bruno'} %&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Nesse caso estou passando uma variável &lt;span style="font-weight: bold;"&gt;name&lt;/span&gt; com o valor &lt;span style="font-weight: bold;"&gt;"Bruno"&lt;/span&gt; para o partial &lt;span style="font-weight: bold;"&gt;example&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mas qual é a utilidade disso?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Vou dar um exemplo prático que aconteceu comigo esses dias.&lt;br /&gt;&lt;br /&gt;Minha aplicação tem um model &lt;span style="font-weight: bold;"&gt;User&lt;/span&gt; e, ao criar as views para manipular esse model, percebi que o formulário da view &lt;span style="font-weight: bold;"&gt;new&lt;/span&gt; e o da view &lt;span style="font-weight: bold;"&gt;edit&lt;/span&gt; eram idênticos. Então nada melhor do que colocar esse conteúdo dentro de um partial e reaproveitar o código ao bom e velho estilo DRY (&lt;span style="font-style: italic;"&gt;Don't Repeat Yourself&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Fiz isso e meu partial ficou próximo ao do exemplo (clique na imagem para ampliar):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SnozjlTPu8I/AAAAAAAAAP0/ZCEGa6u7WbQ/s1600-h/partial_inicial.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 141px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SnozjlTPu8I/AAAAAAAAAP0/ZCEGa6u7WbQ/s400/partial_inicial.png" alt="" id="BLOGGER_PHOTO_ID_5366658592366640066" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A partir daí eu renderizei esse partial nas duas views (&lt;span style="font-weight: bold;"&gt;new&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;edit&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Só que depois de um tempo eu resolvi retirar alguns campos da view de cadastramento (&lt;span style="font-weight: bold;"&gt;new&lt;/span&gt;) para poder tornar o cadastro mais rápido, atraindo mais usuários. Para isso eu removi os campos &lt;span style="font-weight: bold;"&gt;name&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;last_name&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Uma vez que agora as views &lt;span style="font-weight: bold;"&gt;new&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;edit&lt;/span&gt; são diferentes, eu só posso manter no partial o que é comum às duas, então mantive no partial apenas a parte interna do formulário, com exceção dos campos mencionados. O partial ficou assim:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/Snoz5eENmrI/AAAAAAAAAP8/b3sgvJUlgAI/s1600-h/partial_novo.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 69px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/Snoz5eENmrI/AAAAAAAAAP8/b3sgvJUlgAI/s400/partial_novo.png" alt="" id="BLOGGER_PHOTO_ID_5366658968381659826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;E para renderizar esse partial, eu deixei a view como de costume (&lt;span style="font-weight: bold;"&gt;render :partial&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/Sno0GbNumdI/AAAAAAAAAQE/u84AhBXDlmg/s1600-h/view_errada.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 106px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/Sno0GbNumdI/AAAAAAAAAQE/u84AhBXDlmg/s400/view_errada.png" alt="" id="BLOGGER_PHOTO_ID_5366659190954564050" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;O problema é que, o objeto &lt;span style="font-weight: bold;"&gt;"f"&lt;/span&gt; que é passado ao bloco do helper &lt;span style="font-weight: bold;"&gt;form_for&lt;/span&gt; está sendo criado na view e não existe dentro do partial. Quando o partial tentar acessar o &lt;span style="font-weight: bold;"&gt;"f"&lt;/span&gt; retornará um erro dizendo &lt;span style="font-weight: bold;"&gt;"undefined local variable or method `f'"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Para resolver esse problema, eu vou enviar para o partial o objeto &lt;span style="font-weight: bold;"&gt;"f"&lt;/span&gt;, para que ele exista em seu escopo e solucione o meu problema.&lt;br /&gt;&lt;br /&gt;Resultado (linha 4):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/Sno0WlAqOEI/AAAAAAAAAQM/z39i2lKqQoM/s1600-h/view_corrigida.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 103px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/Sno0WlAqOEI/AAAAAAAAAQM/z39i2lKqQoM/s400/view_corrigida.png" alt="" id="BLOGGER_PHOTO_ID_5366659468462012482" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Problema resolvido!&lt;br /&gt;&lt;br /&gt;É isso aí pessoal, espero que a dica ajude alguém que esteja com esse problema, ou pelo menos incentive o reaproveitamento de código nas views.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-7380175931046547092?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/7380175931046547092/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=7380175931046547092' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7380175931046547092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7380175931046547092'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/08/enviar-parametros-para-um-partial.html' title='Enviar parâmetros para um partial'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/SnozjlTPu8I/AAAAAAAAAP0/ZCEGa6u7WbQ/s72-c/partial_inicial.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4635412447943268493</id><published>2009-08-02T20:34:00.003-03:00</published><updated>2009-08-02T20:49:34.931-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails na prática'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Definir o timezone de seu projeto Rails</title><content type='html'>Se você criar um projeto rails aqui no Brasil e não definir o timezone, perceberá que as horas estarão sendo exibidas de forma errada.&lt;br /&gt;&lt;br /&gt;Isso acontece porque a partir da versão 2.1 o Rails corrige as horas para o timezone UTC por padrão.&lt;br /&gt;&lt;br /&gt;O timezone é definido no arquivo &lt;span style="font-weight: bold;"&gt;config/environment.rb&lt;/span&gt;, você encontrará a seguinte linha nesse arquivo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;config.time_zone = 'UTC'&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Para saber qual é a nomenclatura do timezone da sua região você pode utilizar o comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rake time:zones:local&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;No meu caso, o resultado é:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;* UTC -03:00 *&lt;br /&gt;Brasilia&lt;br /&gt;Buenos Aires&lt;br /&gt;Georgetown&lt;br /&gt;Greenland&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E a opção que mais se enquadra para mim é "Brasilia", então irei alterar a linha de meu &lt;span style="font-weight: bold;"&gt;environment.rb&lt;/span&gt; para:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;config.time_zone = 'Brasilia'&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Agora basta reiniciar o servidor e as horas estarão sendo exibidas da forma correta para a minha região.&lt;br /&gt;&lt;br /&gt;Abraços.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4635412447943268493?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4635412447943268493/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4635412447943268493' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4635412447943268493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4635412447943268493'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/08/definir-o-timezone-de-seu-projeto-rails.html' title='Definir o timezone de seu projeto Rails'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-9099105761807413808</id><published>2009-08-02T19:28:00.004-03:00</published><updated>2009-08-02T19:43:08.612-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Criar atalhos para seus comandos no Ubuntu</title><content type='html'>Já que é pra falar de Linux, aí vai mais uma dica rápida.&lt;br /&gt;&lt;br /&gt;Se você tem comandos extensos que utiliza com frequência, você pode simplificar sua vida criando atalhos (alias) para esses comandos.&lt;br /&gt;&lt;br /&gt;Por exemplo, eu acho os comandos pra ligar e desligar o servidor &lt;a href="http://mongrel.rubyforge.org/"&gt;mongrel&lt;/a&gt; um tanto quanto extensos para digitar várias vezes ao dia:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;mongrel_rails start -d&lt;br /&gt;mongrel_rails stop&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Então para me ajudar eu criei alguns alias no arquivo .bashrc que me permitem acessar esses comandos apenas digitando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;mstart&lt;br /&gt;mstop&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Como fazer isso?&lt;br /&gt;&lt;br /&gt;Simples, abra o arquivo .bashrc com o comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;gedit ~/.bashrc&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;(utilizei o gedit porque acho que é um editor acessível a todos, mas você pode usar o que achar melhor)&lt;br /&gt;&lt;br /&gt;Insira no final do arquivo as linhas e salve-o:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;alias mstart="mongrel_rails start -d"&lt;br /&gt;alias mstop="mongrel_rails stop"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;A sintaxe é simples:&lt;br /&gt;&lt;br /&gt;alias nome_do_atalho="comando"&lt;br /&gt;&lt;br /&gt;E a partir daí você pode começar a usar comandos mais curtos!&lt;br /&gt;&lt;br /&gt;Acredito que você precise reiniciar o micro pra começar a funcionar.&lt;br /&gt;&lt;br /&gt;Essa dica foi para Ubuntu mas funciona em outras distribuições do Linux, o que muda as vezes é o nome do arquivo.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-9099105761807413808?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/9099105761807413808/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=9099105761807413808' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/9099105761807413808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/9099105761807413808'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/08/criar-atalhos-para-seus-comandos-no.html' title='Criar atalhos para seus comandos no Ubuntu'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8807755740106857201</id><published>2009-08-02T14:51:00.003-03:00</published><updated>2009-08-02T15:10:37.911-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Procurar arquivos no Linux a partir de um trecho de texto contido nele</title><content type='html'>Hoje darei uma dica sobre Linux que pode ser bem útil em seu dia a dia.&lt;br /&gt;&lt;br /&gt;Vamos dizer que você escreveu um texto em um arquivo certo tempo atrás e hoje você lembra o que tem escrito nele mas não lembra o nome do arquivo. Ou vamos dizer que você alterou o nome de um método em seu projeto e precisa alterar todos os arquivos que usam o método com o nome antigo. Como encontrar esses arquivos?&lt;br /&gt;&lt;br /&gt;Para procurar arquivos em um diretório a partir de um trecho contido dentro do dele existe o comando &lt;span style="font-weight: bold;"&gt;grep&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Por exemplo, vamos dizer que eu queira encontrar todos os arquivos que contém o trecho de texto "user" dentro do diretório atual.&lt;br /&gt;&lt;br /&gt;Eu usaria:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;grep "user" *&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;A sintaxe é &lt;span style="font-weight: bold;"&gt;"grep opções texto arquivo"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Eu posso usar também:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;grep -Ri "user" *&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;O "R" diz pra ele procurar também em subpastas e o "i" diz pra ele não diferenciar maiúsculas de minúsculas.&lt;br /&gt;&lt;br /&gt;Poderia melhorar utilizando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;grep -Rin "user" *&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Com a opção "n" ele me retornaria também o número da linha em que o texto foi encontrado.&lt;br /&gt;&lt;br /&gt;O grep pode ser usado também para filtrar o resultado de um outro comando, por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;lspci | grep "nVidia"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;As aspas são opcionais para textos de uma palavra só.&lt;br /&gt;&lt;br /&gt;Espero que a dica ajude. Na verdade eu estava tentando encontrar um arquivo que continha um trecho de código em meu projeto e o &lt;a href="http://twitter.com/vinibaggio"&gt;Vinícius Baggio&lt;/a&gt; me ensinou como fazer (obrigado!). Aí como achei bem útil resolvi vir aqui e passar a informação adiante.&lt;br /&gt;&lt;br /&gt;Abraços.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8807755740106857201?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8807755740106857201/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8807755740106857201' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8807755740106857201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8807755740106857201'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/08/procurar-arquivos-no-linux-partir-de-um.html' title='Procurar arquivos no Linux a partir de um trecho de texto contido nele'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8222783146487925585</id><published>2009-07-29T21:25:00.005-03:00</published><updated>2009-07-29T21:53:43.922-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='livros'/><title type='text'>Dica de livro: Startup, Jessica Livingston</title><content type='html'>Essa semana acabei de ler o livro &lt;span style="font-weight: bold;"&gt;Startup&lt;/span&gt;, de Jessica Livingston.&lt;br /&gt;&lt;br /&gt;O livro conta a história dos fundadores de várias startups do mundo da tecnologia, todas no formato de entrevista.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SnDrsbcjAEI/AAAAAAAAAPs/PSU4uAbNC4M/s1600-h/startup.jpg"&gt;&lt;img style="cursor: pointer; width: 273px; height: 400px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SnDrsbcjAEI/AAAAAAAAAPs/PSU4uAbNC4M/s400/startup.jpg" alt="" id="BLOGGER_PHOTO_ID_5364046304712523842" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Eu estava em dúvida se iria gostar do livro, uma vez que podia ser que ele fosse muito voltado para o lado de negócios e isso não me atrai tanto. Mas ele foi surpreendentemente proveitoso, acredito que o livro que eu mais gostei dentre os últimos que li.&lt;br /&gt;&lt;br /&gt;As histórias são incríveis, contam tanto o lado do negócio quanto parte do lado tecnológico.&lt;br /&gt;&lt;br /&gt;A escolha dos entrevistados também foi excelente, vou listá-los abaixo:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Steve Wozniak, Apple Computer&lt;/li&gt;&lt;li&gt;Mike Lazaridis, Research In Motion (criadora do BlackBerry)&lt;/li&gt;&lt;li&gt;Sabeer Bhatia, Hotmail&lt;/li&gt;&lt;li&gt;Evan Williams, Pyra Labs (Blogger.com)&lt;/li&gt;&lt;li&gt;Tim Brady, Yahoo!&lt;/li&gt;&lt;li&gt;Paul Buchheit, Gmail&lt;/li&gt;&lt;li&gt;Craig Newmark, craigslist&lt;/li&gt;&lt;li&gt;Caterina Fake, Flickr&lt;/li&gt;&lt;li&gt;Charles Geschke, Adobe Systems&lt;/li&gt;&lt;li&gt;Blake Ross, Firefox&lt;/li&gt;&lt;li&gt;Bob Davis, Lycos&lt;/li&gt;&lt;li&gt;Max Levchin, PayPal&lt;/li&gt;&lt;li&gt;Mitchell Kapor, Lotus Development&lt;/li&gt;&lt;li&gt;Steve Perlman, WebTV&lt;/li&gt;&lt;li&gt;Mark Fletcher, ONElist, Bloglines&lt;/li&gt;&lt;li&gt;David Heinemeier Hansson, 37signals&lt;/li&gt;&lt;/ul&gt;A maior semelhança entre todas as histórias de sucesso é o foco em criar um produto de qualidade.&lt;br /&gt;&lt;br /&gt;Outro ponto interessante no livro é ver como as empresas do Vale do Silício são ligadas de uma certa forma.&lt;br /&gt;&lt;br /&gt;Recomendo totalmente a leitura, mesmo para quem não é do ramo da tecnologia.&lt;br /&gt;&lt;br /&gt;O livro é em português, e para quem quiser a versão original em inglês, o nome é &lt;span style="font-weight: bold;"&gt;Founders at Work&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Mas a tradução não trás nenhum problema grave, só identifiquei alguns erros de digitação, mas muito poucos e não atrapalham na leitura.&lt;br /&gt;&lt;br /&gt;Fica a dica então. Aproveito pra falar para quem estiver procurando livros, visite a &lt;a href="http://brunograsselli.com.br/search/label/livros"&gt;&lt;span style="font-weight: bold;"&gt;tag de livros&lt;/span&gt;&lt;/a&gt; do blog, que está ficando com um conteúdo muito bom.&lt;br /&gt;&lt;br /&gt;Estou incluindo nela apenas os livros em que identifico um certo nível de qualidade após concluir a leitura.&lt;br /&gt;&lt;br /&gt;Os próximos que eu irei ler são: "Ruby by example" e "Agile estimating and planning", mas ainda estou esperando chegar. Após concluí-los eu comento aqui.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8222783146487925585?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8222783146487925585/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8222783146487925585' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8222783146487925585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8222783146487925585'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/07/dica-de-livro-startup-jessica.html' title='Dica de livro: Startup, Jessica Livingston'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_CGnpveaIy_M/SnDrsbcjAEI/AAAAAAAAAPs/PSU4uAbNC4M/s72-c/startup.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4160633660813754389</id><published>2009-07-28T20:45:00.003-03:00</published><updated>2009-07-28T20:54:28.739-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software livre'/><title type='text'>Questionário para melhorar o Software Livre</title><content type='html'>Gostaria de ajudar a divulgar a pesquisa para identificar problemas de comunicação em projetos de software livre que o Fabio Kung postou na lista de discussões do &lt;a href="http://groups.google.com.br/group/rails-br?pli=1"&gt;rails-br&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Segue o texto dele:&lt;br /&gt;&lt;blockquote&gt;&lt;div&gt;Olá a todos,&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;O meu amigo Hugo Corbucci está fazendo uma pesquisa, como parte da sua pesquisa no mestrado, para identificar problemas de comunicação e possíveis soluções.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; Se você contribui (ou já contribuiu) para o software livre e puder gastar alguns minutinhos, se importaria em responder o questionário?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ime.usp.br/%7Ecorbucci/floss-survey.html"&gt;http://www.ime.usp.br/~corbucci/floss-survey.html&lt;/a&gt;&lt;br /&gt;&lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Eu e o Hugo agradecemos! Quem puder divulgar por aí também seria de muita ajuda.&lt;/div&gt;   &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[]'s&lt;/div&gt;&lt;br /&gt;-- Fabio Kung&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;É isso aí pessoal, quem puder contribuir respondendo ou divulgando (blog, twitter, amigos) eu agradeço.&lt;br /&gt;&lt;br /&gt;Abraços.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4160633660813754389?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4160633660813754389/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4160633660813754389' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4160633660813754389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4160633660813754389'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/07/questionario-para-melhorar-o-software.html' title='Questionário para melhorar o Software Livre'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5967816715482776934</id><published>2009-07-26T14:59:00.009-03:00</published><updated>2009-07-26T23:09:05.759-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='evento'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Quinto encontro GURU-SP</title><content type='html'>Final de semana passado aconteceu aqui em São Paulo o quinto encontro do &lt;a href="http://www.guru-sp.org/"&gt;GURU-SP&lt;/a&gt; (Grupo de Usuários Ruby de São Paulo). Foi perto do viaduto do chá, numa sala de reuniões que foi gentilmente cedida pelo pessoal da &lt;a href="http://www.voicetechnology.com.br/"&gt;Voice Technology&lt;/a&gt;, (bela iniciativa, valeu mesmo!).&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/Smyb08q3HzI/AAAAAAAAAPU/_cnUjeJ4ZNM/s1600-h/5_encontro_guru_sp_git.JPG"&gt;&lt;img style="cursor: pointer; width: 400px; height: 266px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/Smyb08q3HzI/AAAAAAAAAPU/_cnUjeJ4ZNM/s400/5_encontro_guru_sp_git.JPG" alt="" id="BLOGGER_PHOTO_ID_5362832590232821554" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;&lt;br /&gt;Palestra sobre GIT com o Douglas "QMX" Campos&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;O Guru-SP é um grupo de usuários que fala sobre Ruby, Rails e outros assuntos referentes a Agile. Nos reunimos com frequência para trocar conhecimentos. Esse foi o quinto encontro do grupo, e o terceiro que participo.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/Smyb8BN3xII/AAAAAAAAAPc/sskYguH3Th8/s1600-h/5_encontro_guru_so_coding_dojo.JPG"&gt;&lt;img style="cursor: pointer; width: 400px; height: 266px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/Smyb8BN3xII/AAAAAAAAAPc/sskYguH3Th8/s400/5_encontro_guru_so_coding_dojo.JPG" alt="" id="BLOGGER_PHOTO_ID_5362832711712490626" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;Coding Dojo no final da tarde&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Nosso encontro começou pela manhã com uma apresentação de todos presentes e uma ótima introdução ao Rails comandada pelo &lt;a href="http://twitter.com/rafaelrosafu"&gt;Rafael Rosa "Fu"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Depois fizemos uma pausa para o almoço e quando voltamos o Rafael mandou mais uma ótima palestra, dessa vez um pouco mais avançada, sobre o ORM Data Mapper. O qual me impressionou muito, é uma boa opção para vários projetos (principalmente os que envolvem bancos legados) e vai ficar ainda mais viável quando vier o Rails 3.0 com a possibilidade de trabalhar com outros ORM de forma mais fácil.&lt;br /&gt;&lt;br /&gt;A próxima palestra foi do &lt;a href="http://www.twitter.com/qmx"&gt;Douglas Campos&lt;/a&gt; sobre o GIT. O cara entende muito de GIT e a palestra foi muito boa, pudemos até interagir num projetinho que fizemos no meio da palestra (alguns scaffolds) e ficamos simulando situações com o GIT (algumas até que não estavam previstas, mas que o Douglas soube se virar muito bem - desculpa pelos pushs inesperados!).&lt;br /&gt;&lt;br /&gt;No final da tarde ainda fizemos um coding dojo, onde o &lt;a href="http://twitter.com/vinibaggio"&gt;Vinícius Baggio&lt;/a&gt; foi a frente para manipular o projeto que criamos todos juntos, para abordar temas como testes com Rspec e Remarkable.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SmyiO1cRHzI/AAAAAAAAAPk/6wfcOi2EqTQ/s1600-h/logo_guru-sp.jpg"&gt;&lt;img style="cursor: pointer; width: 180px; height: 175px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SmyiO1cRHzI/AAAAAAAAAPk/6wfcOi2EqTQ/s400/logo_guru-sp.jpg" alt="" id="BLOGGER_PHOTO_ID_5362839632038928178" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Esse foi um resumo geral, todas as palestras e o encontro como um todo foi muito proveitoso. Dessa vez a galera compareceu em massa (acho que cerca de uns 25 participantes ou mais) e é muito legal ver o grupo crescendo desse jeito.&lt;br /&gt;&lt;br /&gt;Com certeza teremos próximos encontros, acredito que o próximo deve ser marcado para setembro. Se você ainda não participa do grupo mas tem interesse, participe da nossa &lt;a href="http://groups.google.com.br/group/ruby-sp?pli=1"&gt;lista de discussões&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As fotos do evento estão disponíveis no link abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://apantaliao.multiply.com/photos/album/29/Encontro_Guru-sp"&gt;http://apantaliao.multiply.com/photos/album/29/Encontro_Guru-sp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Informações mais detalhadas sobre o evento, assim como vídeos das palestras e outros posts sobre ele podem ser encontrados na página oficial no GURU-SP:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://guru-sp.com/index.php/Quinto_Encontro"&gt;http://guru-sp.com/index.php/Quinto_Encontro&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Abraços pessoal e espero que os próximos encontros continuem sempre crescendo com qualidade, assim como está acontecendo.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5967816715482776934?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5967816715482776934/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5967816715482776934' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5967816715482776934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5967816715482776934'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/07/quinto-encontro-guru-sp.html' title='Quinto encontro GURU-SP'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/Smyb08q3HzI/AAAAAAAAAPU/_cnUjeJ4ZNM/s72-c/5_encontro_guru_sp_git.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5285473207812718599</id><published>2009-07-20T22:17:00.003-03:00</published><updated>2009-07-20T22:51:48.739-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails 2.3.3 liberado!</title><content type='html'>Post rápido para avisar que hoje a tarde foi lançada a versão 2.3.3 do Ruby on Rails.&lt;br /&gt;&lt;br /&gt;Essa versão contém algumas correções de bugs e algumas novas características, como o método touch para atualizar timestamps de um registro, a opção :primary_key para o belongs_to do ActiveRecord entre outros, como melhorias para utilizar JSON.&lt;br /&gt;&lt;br /&gt;Para maiores informações visitem:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://weblog.rubyonrails.org/2009/7/20/rails-2-3-3-touching-faster-json-bug-fixes"&gt;http://weblog.rubyonrails.org/2009/7/20/rails-2-3-3-touching-faster-json-bug-fixes&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para fazer a atualização basta utilizar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo gem update rails&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5285473207812718599?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5285473207812718599/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5285473207812718599' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5285473207812718599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5285473207812718599'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/07/rails-233-liberado.html' title='Rails 2.3.3 liberado!'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-7764897604016984575</id><published>2009-07-19T19:01:00.006-03:00</published><updated>2009-07-19T20:11:39.033-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento ágil'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Review do curso Certified Scrum Master</title><content type='html'>Essa semana participei do curso &lt;a href="http://www.caelum.com.br/curso/csm-certified-scrum-master/"&gt;&lt;span style="font-weight: bold;"&gt;Certified Scrum Master Training&lt;/span&gt;&lt;/a&gt; que é o curso oficial para Scrum Masters da &lt;a href="http://www.scrumalliance.org/"&gt;Scrum Alliance,&lt;/a&gt; lecionado no Brasil pelo &lt;a href="http://www.scrumalliance.org/profiles/1939-alexandre-magno"&gt;Alexandre Magno&lt;/a&gt; (Certified Scrum Trainer), numa parceria &lt;a href="http://www.adaptworks.com/"&gt;Adaptworks&lt;/a&gt; e &lt;a href="http://www.caelum.com.br/"&gt;Caelum&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O curso aconteceu entre os dias 13 e 16 de julho e estou completamente satisfeito. O Alexandre domina completamente o assunto e ensina de um jeito supreendente, cheio de atividades para nos fazer entender melhor o conteúdo.&lt;br /&gt;&lt;br /&gt;Não vou entrar em detalhes quanto as atividades, pois deixo a surpresa pra quem pretende fazer o curso.&lt;br /&gt;&lt;br /&gt;Apesar do curso ter acontecido a noite e todos estarmos muito cansados, o Alexandre conseguiu prender a atenção de todos e responder a todas as perguntas dos alunos satisfatoriamente, usando sua ampla experiência profissional para exemplificar.&lt;br /&gt;&lt;br /&gt;O Scrum é muito diferente do que eu imaginava, até mais atraente do que minha ideia inicial, mas muito mais difícil de ser implantado do que eu previa.&lt;br /&gt;&lt;br /&gt;As instalações do curso foram em local adequado (hotel &lt;a href="http://www.greenplaceflat.com.br/portugues/"&gt;Green Place Flat&lt;/a&gt;) e de fácil acesso, pelo menos para mim.&lt;br /&gt;&lt;br /&gt;Esse era um curso que eu já pretendia fazer há algum tempo, mas tinha lá minhas dúvidas se eu gostaria e se valeria o investimento.&lt;br /&gt;&lt;br /&gt;Como já disse, estou completamente satisfeito de ter feito o curso e se você está com essas mesmas dúvidas te indico que faça também.&lt;br /&gt;&lt;br /&gt;Agora que tenho certo conhecimento de Scrum, posso dizer que é arriscado fazer um curso de Scrum em uma instituição que não aborde o tema da forma correta.&lt;br /&gt;&lt;br /&gt;Pois ele apesar de simples, é difícil, e se for dado importância só para os processos (que geralmente é o que mais atrái todo mundo e muita gente pensa que Scrum é só isso) e deixar a cultura do Scrum de lado (que é o mais importante) com certeza você ao implantá-lo, apesar de ter seus desenvolvedores trabalhando com sprints, daily meetings, planning poker, etc, o que te dará a falsa impressão de estar trabalhando com Scrum, não terá os ganhos que o Scrum de verdade lhe proporciona.&lt;br /&gt;&lt;br /&gt;Gostaria de dizer que não estou ganhando nada com esse post, só estou recomendando um curso que achei que deu retorno ao investimento.&lt;br /&gt;&lt;br /&gt;Abraços e provavelmente eu devo começar a abordar o assunto Scrum aqui nos posts do blog, uma vez que pretendo me aprofundar mais com ele.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-7764897604016984575?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/7764897604016984575/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=7764897604016984575' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7764897604016984575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7764897604016984575'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/07/review-do-curso-certified-scrum-master.html' title='Review do curso Certified Scrum Master'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-3906277224073650909</id><published>2009-07-11T17:28:00.016-03:00</published><updated>2009-07-11T18:39:35.735-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails na prática'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='dry'/><category scheme='http://www.blogger.com/atom/ns#' term='layouts'/><title type='text'>Layouts aninhados no Rails usando content_for</title><content type='html'>A criação de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;layouts&lt;/span&gt; em aplicações &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Ruby&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;on&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Rails&lt;/span&gt; é uma funcionalidade que  valorizo muito no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;framework&lt;/span&gt;. Com ela podemos implementar na prática a filosofia de &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Design&lt;/span&gt; de Epicentro&lt;/span&gt; (ver livro &lt;a href="http://gettingreal.37signals.com/GR_por.php"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Getting&lt;/span&gt; Real&lt;/a&gt; - 37&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;signals&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Por padrão, podemos criar dois tipos de arquivos de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;layouts&lt;/span&gt; no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Rails&lt;/span&gt;:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Layout&lt;/span&gt; para &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;controllers&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Layout&lt;/span&gt; para a aplicação inteira&lt;/li&gt;&lt;/ol&gt;Para criar um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;layout&lt;/span&gt; específico para um determinado &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;controller&lt;/span&gt;, criamos dentro da pasta &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;app&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;views&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;layouts&lt;/span&gt; da aplicação um arquivo com o nome:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;nome_do_controller.html.erb&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;albums.html.erb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Um exemplo simples do conteúdo desse arquivo seria o seguinte:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/Slj7HCcEWhI/AAAAAAAAAN8/cKbmhQHDmrw/s1600-h/layout_basico.png"&gt;&lt;img style="cursor: pointer; width: 160px; height: 94px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/Slj7HCcEWhI/AAAAAAAAAN8/cKbmhQHDmrw/s400/layout_basico.png" alt="" id="BLOGGER_PHOTO_ID_5357307855089457682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Aonde invocamos o método &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;yield&lt;/span&gt; será exibido o conteúdo da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;view&lt;/span&gt; da página que estará sendo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;acessada&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Se criarmos um arquivo parecido mas com o nome de &lt;span style="font-weight: bold;"&gt;application.html.erb&lt;/span&gt;, esse &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;layout&lt;/span&gt; irá ser exibido em todas as páginas da aplicação, a menos que exista um arquivo de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;layout&lt;/span&gt; para o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;controller&lt;/span&gt; em questão (como &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_24"&gt;mencionado&lt;/span&gt; acima) ou tenha sido informado de forma explícita um outro &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;layout&lt;/span&gt; a ser exibido (demonstrarei como em breve).&lt;br /&gt;&lt;br /&gt;O que acontece é que muitas vezes precisamos de dois ou mais &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;layouts&lt;/span&gt; diferentes em nossa aplicação, mas parte desses &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;layouts&lt;/span&gt; são iguais entre si. E replicar essas partes iguais em todos os &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;layouts&lt;/span&gt; fere o princípio de &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;DRY&lt;/span&gt;&lt;/a&gt; (Don't &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;Repeat&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;Yourself&lt;/span&gt;) e acaba causando uma série de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;re&lt;/span&gt;trabalhos.&lt;br /&gt;&lt;br /&gt;Imagine que você altere essa parte repetida do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;layout&lt;/span&gt; em um dos arquivos e esquece de mudar nos demais?&lt;br /&gt;&lt;br /&gt;Para isso, vou lhes apresentar uma solução que utilizei esses dias em uma aplicação minha. Na verdade encontrei essa solução no endereço abaixo, e apenas dei uma pequena adaptada para ficar mais fácil de trabalhar:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.jerodsanto.net/2008/06/rails-nested-layouts"&gt;http://blog.jerodsanto.net/2008/06/rails-nested-layouts&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Imagine que o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;layout&lt;/span&gt; de nosso site é parecido com a figura abaixo:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/Slj7hXP2XgI/AAAAAAAAAOE/hzoPe-UPkKc/s1600-h/rails_layout_padrao.gif"&gt;&lt;img style="cursor: pointer; width: 231px; height: 192px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/Slj7hXP2XgI/AAAAAAAAAOE/hzoPe-UPkKc/s400/rails_layout_padrao.gif" alt="" id="BLOGGER_PHOTO_ID_5357308307351952898" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Onde possuímos um espaço para o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;logotipo&lt;/span&gt;, um espaço para o conteúdo e um espaço para uma &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;sidebar&lt;/span&gt; que contém o menu.&lt;br /&gt;&lt;br /&gt;Agora imagine que em determinada parte do sites precisamos exibir algumas fotografias grandes, e seria preciso retirar o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;sidebar&lt;/span&gt; para poupar espaço.&lt;br /&gt;&lt;br /&gt;Para não termos que criar dois &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;layouts&lt;/span&gt; praticamente idênticos, faremos eles com apenas as partes que são diferentes, e o que for igual deixaremos em um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;layout&lt;/span&gt; separado, o qual os dois incluirão. Conforme demonstrado na figura:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/Slj7tHv-fbI/AAAAAAAAAOM/XcHuuZ8p-f8/s1600-h/rails_nested_layouts.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 311px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/Slj7tHv-fbI/AAAAAAAAAOM/XcHuuZ8p-f8/s400/rails_nested_layouts.png" alt="" id="BLOGGER_PHOTO_ID_5357308509350165938" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Podemos chamar isso de &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;layouts&lt;/span&gt; aninhados&lt;/span&gt;, ou, no termo em inglês, &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;nested&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;layouts&lt;/span&gt;&lt;/span&gt;. Onde dois &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;layouts&lt;/span&gt; simples herdam informações de um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;layout&lt;/span&gt; que trás informações comuns aos dois.&lt;br /&gt;&lt;br /&gt;Para nos ajudar a implementar nossa solução utilizaremos um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;helper&lt;/span&gt; do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;Rails&lt;/span&gt; chamado &lt;a href="http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#M002048"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;content&lt;/span&gt;_for&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Com &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;content&lt;/span&gt;_for&lt;/span&gt; podemos armazenar o conteúdo de uma determinada parte do nosso site para ser exibida depois em algum lugar específico, por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/Slj8YI5BIMI/AAAAAAAAAOU/fYzT_2Kp0CA/s1600-h/content_for.png"&gt;&lt;img style="cursor: pointer; width: 244px; height: 308px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/Slj8YI5BIMI/AAAAAAAAAOU/fYzT_2Kp0CA/s400/content_for.png" alt="" id="BLOGGER_PHOTO_ID_5357309248390897858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;O que é armazenado dentro do bloco do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;helper&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;content&lt;/span&gt;_for&lt;/span&gt; é exibido depois em:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;%= yield :list %&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Então para solucionar nosso problema nós iremos criar dois &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;layouts&lt;/span&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;application.html.erb (que contém o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;sidebar&lt;/span&gt; e será exibido em todas as páginas da aplicação)&lt;/li&gt;&lt;li&gt;expanded_content.html.erb (que será exibido apenas nas páginas que precisam de mais espaço para o conteúdo)&lt;/li&gt;&lt;/ul&gt;E um outro arquivo que conterá toda a base do site:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;base.html.erb&lt;/li&gt;&lt;/ul&gt;Tanto o &lt;span style="font-weight: bold;"&gt;application.html.erb&lt;/span&gt; quanto o &lt;span style="font-weight: bold;"&gt;expanded_content.html.erb&lt;/span&gt; definirão o que deverá constar no &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;content&lt;/span&gt;_for :&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;content&lt;/span&gt;&lt;/span&gt;, e depois &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_55"&gt;renderizarão&lt;/span&gt; o &lt;span style="font-weight: bold;"&gt;base.html.erb&lt;/span&gt;, que contém um lugar definido para exibir o conteúdo de &lt;span style="font-weight: bold;"&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;content&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;application.html.erb&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/Slj9v0re5VI/AAAAAAAAAOk/nxwG-u2UdKM/s1600-h/application.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 157px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/Slj9v0re5VI/AAAAAAAAAOk/nxwG-u2UdKM/s400/application.png" alt="" id="BLOGGER_PHOTO_ID_5357310754793907538" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;expanded_content.html.erb&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/Slj97UMXhgI/AAAAAAAAAOs/lxRgk04J4no/s1600-h/expanded.png"&gt;&lt;img style="cursor: pointer; width: 394px; height: 113px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/Slj97UMXhgI/AAAAAAAAAOs/lxRgk04J4no/s400/expanded.png" alt="" id="BLOGGER_PHOTO_ID_5357310952231896578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;base.html.erb&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SlkBMC9t6LI/AAAAAAAAAPM/mI5WVKkgbBU/s1600-h/base.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 218px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SlkBMC9t6LI/AAAAAAAAAPM/mI5WVKkgbBU/s400/base.png" alt="" id="BLOGGER_PHOTO_ID_5357314538199705778" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Eu coloquei o conteúdo do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;sidebar&lt;/span&gt; dentro de um &lt;a href="http://api.rubyonrails.org/classes/ActionView/Partials.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_58"&gt;partial&lt;/span&gt;&lt;/a&gt;, para melhorar a visualização do exemplo.&lt;br /&gt;&lt;br /&gt;Do jeito que está, todas as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;views&lt;/span&gt; serão exibidas utilizando o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;layout&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;application.html.erb&lt;/span&gt;, uma vez que ele é o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_61"&gt;layout&lt;/span&gt; padrão da aplicação e "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_62"&gt;expanded&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_63"&gt;content&lt;/span&gt;" não é o nome de um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_64"&gt;controller&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Então como eu faço para utilizar o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_65"&gt;layout&lt;/span&gt; expanded_content.html.erb?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Você tem duas opções:&lt;br /&gt;&lt;br /&gt;1) Se você deseja aplicar este &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_66"&gt;layout&lt;/span&gt; à todas as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_67"&gt;views&lt;/span&gt; de um determinado &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_68"&gt;controller&lt;/span&gt;, basta adicionar a seguinte linha no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_69"&gt;controller&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_70"&gt;layout&lt;/span&gt; '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_71"&gt;expanded&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_72"&gt;content&lt;/span&gt;'&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Exemplo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SlkAiSakIPI/AAAAAAAAAO8/hZbGdfsP95c/s1600-h/controller.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 148px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SlkAiSakIPI/AAAAAAAAAO8/hZbGdfsP95c/s400/controller.png" alt="" id="BLOGGER_PHOTO_ID_5357313820792725746" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2) Se você deseja aplicar esse &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_73"&gt;layout&lt;/span&gt; apenas a uma determinada &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_74"&gt;action&lt;/span&gt; de seu &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_75"&gt;controller&lt;/span&gt;, basta informar o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_76"&gt;layout&lt;/span&gt; na hora de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_77"&gt;renderizar&lt;/span&gt; a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_78"&gt;view&lt;/span&gt;, exemplo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SlkA-exNiDI/AAAAAAAAAPE/2QnlQ7jePRE/s1600-h/action.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 127px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SlkA-exNiDI/AAAAAAAAAPE/2QnlQ7jePRE/s400/action.png" alt="" id="BLOGGER_PHOTO_ID_5357314305145276466" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Com isso não duplicamos código e podemos administrar melhor nossa aplicação.&lt;br /&gt;&lt;br /&gt;Gostaria de agradecer ao &lt;a href="http://www.google.com/profiles/shairon.toledo"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_79"&gt;Shairon&lt;/span&gt; Toledo&lt;/a&gt; que me falou da existência do &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_80"&gt;content&lt;/span&gt;_for&lt;/span&gt; la no grupo &lt;a href="http://groups.google.com.br/group/rails-br"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_81"&gt;rails&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_82"&gt;br&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Espero que tenho gostado da dica.&lt;br /&gt;&lt;br /&gt;Qualquer dúvida podem entrar em &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_83"&gt;contato&lt;/span&gt; (e-mail, comentário, &lt;a href="http://twitter.com/grasselli"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_84"&gt;twitter&lt;/span&gt;&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Abraços!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-3906277224073650909?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/3906277224073650909/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=3906277224073650909' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3906277224073650909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3906277224073650909'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/07/layouts-aninhados-no-rails-usando.html' title='Layouts aninhados no Rails usando content_for'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_CGnpveaIy_M/Slj7HCcEWhI/AAAAAAAAAN8/cKbmhQHDmrw/s72-c/layout_basico.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2424667415037120121</id><published>2009-07-04T11:35:00.004-03:00</published><updated>2009-07-04T12:06:13.503-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='rake'/><title type='text'>Listando anotações em aplicações Rails utilizando o Rake</title><content type='html'>Recentemente comecei a ler o livro do &lt;a href="http://twitter.com/urubatan"&gt;Rodrigo Urubatan&lt;/a&gt;, &lt;a href="http://www.novatec.com.br/livros/rubyonrails/"&gt;Desenvolvimento Fácil e Rápido de Aplicações Web Ruby on Rails&lt;/a&gt;, tinha comprado faz algum tempo, mas ele entrou na fila dos livros que eu já estava lendo.&lt;br /&gt;&lt;br /&gt;Agora de manhã, na parte que ele ensinava como listar as funcionalidades do utilitário &lt;span style="font-weight: bold;"&gt;Rake&lt;/span&gt; (&lt;span style="font-style: italic;"&gt;rake -T&lt;/span&gt;) e descrevia as mais importantes, me interessei bastante por uma delas, acho que vai facilitar o desenvolvimento de algumas aplicações minhas.&lt;br /&gt;&lt;br /&gt;Estou falando do comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rake notes&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Este comando lista todos os comentários em sua aplicação que começam por &lt;span style="font-weight: bold;"&gt;FIXME&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;OPTIMIZE&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;TODO&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Por exemplo, em um controller, eu adicionei o seguinte comentário:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# OPTIMIZE create_pack action needs to be refactored&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Como mostra a imagem (clique para ampliar):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/Sk9tNq7JO0I/AAAAAAAAANk/3E0MyiyNhcs/s1600-h/OPTIMIZE.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 127px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/Sk9tNq7JO0I/AAAAAAAAANk/3E0MyiyNhcs/s400/OPTIMIZE.png" alt="" id="BLOGGER_PHOTO_ID_5354618563594894146" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Quando, no diretório raiz da minha aplicação, eu executo o comando &lt;span style="font-style: italic;"&gt;rake notes&lt;/span&gt;, ele me retorna:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rake notes&lt;br /&gt;(in /home/bruno/projetos/escolinha)&lt;br /&gt;app/controllers/pictures_controller.rb:&lt;br /&gt; * [ 31] [OPTIMIZE] create_pack action needs to be refactored&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Lembrando que por enquanto minha aplicação só tem essa anotação, se existissem outras, ele listaria também.&lt;br /&gt;&lt;br /&gt;Além desse comando, você pode utilizar também:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rake notes:fixme&lt;br /&gt;rake notes:optimize&lt;br /&gt;rake notes:todo&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Que listam tipos de anotações específicos.&lt;br /&gt;&lt;br /&gt;Fica aí a dica, essa é uma funcionalidade que está disponível a partir do Rails 2.0, e ajuda bastante para lembrar o que ainda precisa ser feito.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2424667415037120121?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2424667415037120121/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2424667415037120121' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2424667415037120121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2424667415037120121'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/07/listando-anotacoes-em-aplicacoes-rails.html' title='Listando anotações em aplicações Rails utilizando o Rake'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/Sk9tNq7JO0I/AAAAAAAAANk/3E0MyiyNhcs/s72-c/OPTIMIZE.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8702121205911295818</id><published>2009-06-30T20:35:00.005-03:00</published><updated>2009-06-30T20:43:09.093-03:00</updated><title type='text'>Firefox 3.5 lançado!</title><content type='html'>Post rápido pra divulgar o lançamento da versão 3.5 do Firefox!&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SkqiVmaWzhI/AAAAAAAAANc/0GHoWcS1gSs/s1600-h/firefox.gif"&gt;&lt;img style="cursor: pointer; width: 117px; height: 119px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SkqiVmaWzhI/AAAAAAAAANc/0GHoWcS1gSs/s400/firefox.gif" alt="" id="BLOGGER_PHOTO_ID_5353269599055302162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Visitem: &lt;a href="http://br.mozdev.org/"&gt;http://br.mozdev.org&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8702121205911295818?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8702121205911295818/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8702121205911295818' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8702121205911295818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8702121205911295818'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/06/firefox-35-lancado.html' title='Firefox 3.5 lançado!'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/SkqiVmaWzhI/AAAAAAAAANc/0GHoWcS1gSs/s72-c/firefox.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5909996749620176857</id><published>2009-06-28T19:55:00.005-03:00</published><updated>2009-06-28T20:54:24.613-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='livros'/><title type='text'>Dica de livro: The Pragmatic Programmer</title><content type='html'>Já citei trechos desse livro pela menos duas vezes aqui no blog e, agora que terminei de lê-lo, gostaria de indicá-lo a todos os programadores que passam por aqui.&lt;br /&gt;&lt;br /&gt;O livro &lt;span style="font-weight: bold;"&gt;The Pragmatic Programmer, from journeyman to master&lt;/span&gt; fala sobre programação em geral, sem focar em nenhuma linguagem específica e sim, no ato de programar. Mostra como deve se comportar um programador pragmático, e o que é isso.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/Skf2I7Yk-uI/AAAAAAAAANU/IFDQZDPRKrs/s1600-h/pragmatic_programmer.jpg"&gt;&lt;img style="cursor: pointer; width: 254px; height: 320px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/Skf2I7Yk-uI/AAAAAAAAANU/IFDQZDPRKrs/s320/pragmatic_programmer.jpg" alt="" id="BLOGGER_PHOTO_ID_5352517315393288930" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;O livro foi escrito por &lt;span style="font-weight: bold;"&gt;Andrew Hunt&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;David Thomas&lt;/span&gt;, dois experientes programadores. Recomendo a leitura a todos. O livro mudou minha maneira de programar, com certeza.&lt;br /&gt;&lt;br /&gt;Infelizmente não há uma versão em português do livro, mas para quem tem a possibilidade de ler em inglês, não perca essa oportunidade.&lt;br /&gt;&lt;br /&gt;O livro pode ser comprado &lt;a href="http://www.livrariacultura.com.br/scripts/cultura/resenha/resenha.asp?nitem=384009&amp;amp;sid=94621021911628723014503811&amp;amp;k5=B058EFD&amp;amp;uid="&gt;aqui&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Não é uma propaganda ao site de comércio eletrônico, só estou querendo mostrar que não é difícil comprar um livro internacional pela internet aqui no Brasil. Existem sites que vendem esse tipo de conteúdo quase pelo mesmo preço do item em seu país de origem.&lt;br /&gt;&lt;br /&gt;Abraços, até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5909996749620176857?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5909996749620176857/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5909996749620176857' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5909996749620176857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5909996749620176857'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/06/dica-de-livro-pragmatic-programmer.html' title='Dica de livro: The Pragmatic Programmer'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/Skf2I7Yk-uI/AAAAAAAAANU/IFDQZDPRKrs/s72-c/pragmatic_programmer.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4206060231079737157</id><published>2009-06-24T22:53:00.004-03:00</published><updated>2009-06-24T23:08:15.029-03:00</updated><title type='text'>Proposta de criação de um Hackerspace em São Paulo</title><content type='html'>O Hugo Borges (agaelebe do &lt;a href="http://www.guru-sp.com/"&gt;GURU-SP&lt;/a&gt;) acaba de postar no &lt;a href="http://www.agaelebe.com.br/2009/6/25/hackerspace_em_sao_paulo"&gt;blog&lt;/a&gt; dele uma proposta de um projeto de criar um &lt;a href="http://www.hackerspaces.org/"&gt;Hackerspace&lt;/a&gt; na cidade de São Paulo.&lt;br /&gt;&lt;br /&gt;A ideia dele é muito interessante, seria uma ótima oportunidade para todos os amantes de tecnologia da cidade.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SkLbFQy5rSI/AAAAAAAAANM/kyYLBNGeOo8/s1600-h/Cbase07.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SkLbFQy5rSI/AAAAAAAAANM/kyYLBNGeOo8/s320/Cbase07.jpg" alt="" id="BLOGGER_PHOTO_ID_5351080190723861794" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Convido a todos a ler o post original no blog dele, e também a ajudarem a tornar isso possível.&lt;br /&gt;&lt;br /&gt;Link: &lt;a href="http://www.agaelebe.com.br/2009/6/25/hackerspace_em_sao_paulo"&gt;http://www.agaelebe.com.br/2009/6/25/hackerspace_em_sao_paulo&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Basicamente um hackerspace é um lugar físico, uma espécie de laboratório que reune pessoas interessadas em certos tópicos de estudo, geralmente ligados a tecnologia, como projetos DIY (faça você mesmo), software, eletrônica, robótica, tecnoarte, entre outros. Além da realização destes projetos o hackerspace pode promover minicursos e eventos, buscando disseminar o conhecimento adquirido.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;Abraços.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4206060231079737157?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4206060231079737157/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4206060231079737157' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4206060231079737157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4206060231079737157'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/06/proposta-de-criacao-de-um-hackerspace.html' title='Proposta de criação de um Hackerspace em São Paulo'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_CGnpveaIy_M/SkLbFQy5rSI/AAAAAAAAANM/kyYLBNGeOo8/s72-c/Cbase07.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6290245251908373670</id><published>2009-06-22T22:08:00.005-03:00</published><updated>2009-06-22T22:37:45.877-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dicas de programação'/><category scheme='http://www.blogger.com/atom/ns#' term='orientação a objetos'/><title type='text'>Dicas para refatoramento</title><content type='html'>Hoje li um texto que gostaria de passar adiante. Foi, novamente, no livro &lt;span style="font-weight: bold;"&gt;The Pragmatic Programmer - from journeyman to master&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;-&lt;/span&gt; onde o autor citou algumas dicas de &lt;a href="http://en.wikipedia.org/wiki/Martin_Fowler"&gt;Martin Fowler&lt;/a&gt; a respeito de &lt;span style="font-style: italic; font-weight: bold;"&gt;refactoring&lt;/span&gt; (refatoramento):&lt;br /&gt;&lt;blockquote&gt;&lt;ol&gt;&lt;li&gt;Não tente refatorar e adicionar funcionalidades ao mesmo tempo.&lt;/li&gt;&lt;li&gt;Esteja certo que você tem bons testes antes de começar o refatoramento. Execute os testes sempre que possível. Desta forma você saberá rapidamente se suas alterações quebraram algo.&lt;/li&gt;&lt;li&gt;De passos curtos e cautelosos: mova um campo de uma classe para outra, una dois métodos similares em uma super classe. Refatoramento frequente envolve criar muitas mudanças localizadas que resultam em uma mudança de larga escala. Se você manter seus passos pequenos, e testar depois de cada passo, você evitará &lt;span style="font-style: italic;"&gt;debugs &lt;/span&gt;&lt;span&gt;prolongados.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt; &lt;/blockquote&gt;Martin Fowler é uma figura respeitada na área de desenvolvimento de softwares, principalmente no que diz respeito a orientação a objetos.&lt;br /&gt;&lt;br /&gt;Acredito que essas dicas são valiosas para um bom refatoramento.&lt;br /&gt;&lt;br /&gt;Abraços pessoal, e até o próximo post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6290245251908373670?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6290245251908373670/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6290245251908373670' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6290245251908373670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6290245251908373670'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/06/dicas-para-refatoramento.html' title='Dicas para refatoramento'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-1677342686170385266</id><published>2009-06-19T21:18:00.011-03:00</published><updated>2009-06-19T21:54:07.882-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='traduções'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Entendendo símbolos em Ruby (tradução)</title><content type='html'>Ontem eu estava no &lt;a href="http://groups.google.com.br/group/rails-br"&gt;rails-br&lt;/a&gt; e um integrante do grupo citou o link para um &lt;a href="http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols"&gt;artigo&lt;/a&gt; sobre símbolos no Ruby, escrito por &lt;a href="http://glu.ttono.us/"&gt;Kevin Clark&lt;/a&gt;. Achei o artigo muito útil e resolvi traduzí-lo para o português para ajudar quem estiver com dúvidas em símbolos.&lt;br /&gt;&lt;br /&gt;Sinceramente, eu também aprendi muito com o texto. Eu sabia quando utilizar os símbolos, mas não o porque.&lt;br /&gt;&lt;br /&gt;Então segue abaixo o texto, qualquer crítica quanto à tradução, correção ou outro tipo de comentário será bem vindo. Lembrando que todos os créditos do texto são de &lt;span style="font-weight: bold;"&gt;Kevin Clark&lt;/span&gt;, o autor do original.&lt;br /&gt;&lt;br /&gt;Para quem lê em inglês, este é o link do original:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols"&gt;http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Entendendo símbolos em Ruby&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Símbolos em ruby são um enigma. Nós usamos eles, mas muitos não os entendem realmente.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Então, afinal, o que é um símbolo?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;De uma forma simples, um símbolo é algo que você utiliza para representar nomes e strings. O que se resume a uma forma eficiente de ter nomes descritivos enquanto você economiza espaço que seria utilizado para gerar uma string para cada instância de nome.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;O caso do Dr. Jones&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dr. Jones é um psicólogo. Ele regularmente usa testes de associações de palavras para diagnosticar pacientes e usa ruby para manter um registro de tudo. Seu primeiro paciente, Why, responde dessa maneira:&lt;br /&gt;&lt;br /&gt;Dr J: Vermelho&lt;br /&gt;Why: Ruby&lt;br /&gt;Dr J: Transporte&lt;br /&gt;Why: Rails&lt;br /&gt;Dr J: Pedaçudo&lt;br /&gt;Why: Bacon&lt;br /&gt;&lt;br /&gt;Dr Jones cria um hash para armazenar seus dados:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;why = {"vermelho" =&gt; "ruby", "transporte" =&gt; "rails", "pedaçudo" =&gt; "bacon"}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;O segundo paciente do Dr Jones, Bob, entrega os resultados de sua pesquisa:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;bob = {"vermelho" =&gt; "pintar", "transporte" =&gt; "carro", "pedaçudo" =&gt; "gordo"}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;O problema&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Depois de executar várias centenas de testes de associações de palavras, Dr. Jones começa a perceber que ele está estourando a memória! Num palpite, Jones executa testes no irb:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&gt; paciente1 = {"ruby" =&gt; "vermelho"}&lt;br /&gt;&gt; paciente2 = {"ruby" =&gt; "programação"}&lt;br /&gt;&gt; paciente1.each_key {|key| puts key.object_id.to_s}&lt;br /&gt;211006&lt;br /&gt;&gt; paciente2.each_key {|key| puts key.object_id.to_s}&lt;br /&gt;203536&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Bem, vendo isso, cada vez que ele cria um hash para armazenar sua informação, o ruby cria um novo objeto string em uma diferente localização na memória para cada key. Felizmente, existe uma alternativa.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Símbolo ao resgate!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Diferente de strings, símbolos com um mesmo nome são inicializados e existem na memória uma única vez durante a sessão do ruby. Símbolos são obviamente mais úteis quando você reutiliza strings para representar alguma coisa. Reproduzindo o teste do Dr Jones, nós poderemos ver:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&gt; paciente1 = { :ruby =&gt; "vermelho" }&lt;br /&gt;&gt; paciente2 = { :ruby =&gt; "programação" }&lt;br /&gt;&gt; paciente1.each_key {|key| puts key.object_id.to_s}&lt;br /&gt;3918094&lt;br /&gt;&gt; paciente2.each_key {|key| puts key.object_id.to_s}&lt;br /&gt;3918094&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Usando símbolos, nós utilizamos um único endereço de memória para representar a palavra ruby em nosso teste de associação de palavras. Ao longo do tempo, isso pode poupar bastante espaço.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mas eu não sou um psiquiatra, quando mais eu vou querer usar símbolos?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Símbolos são úteis qualquer hora que você estiver reutilizando uma palavra várias e várias vezes para representar algo, seja ele uma chave em um hash ou o método que você está usando em uma http query.&lt;br /&gt;Um exemplo, do último e melhor e melhor framework web &lt;a href="http://www.rubyonrails.pro.br/"&gt;Ruby on Rails&lt;/a&gt;, é seu uso de símbolos em rotas e links. O Rails define actions dentre os controllers para fazer coisas no framework antes de renderizar uma página web, então um link em Rails pode se parecer com algo assim:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;link_to("Ver Artigo", :controller =&gt; "articles", :action =&gt; "show",&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Quando uma aplicação pode ter centenas de links, ou ao menos centenas de referências para diferentes actions e controllers, é significantemente mais eficiente utilizar símbolos do que strings.&lt;br /&gt;&lt;br /&gt;Finalmente, é importante comentar que a utilidade dos símbolos não é restrita às keys em hashes. Por exemplo, se alguém for escrever um cliente ou servidor http ele pode utilizar get e post diversas vezes dentro da aplicação, e pode ser apropriado usar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;do_this if query == :get&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;send_message_to_server(:post,filename)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Qualquer hora que uma string possa ser usada várias e várias vezes, um símbolo pode ser um bom candidato para substituição.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-1677342686170385266?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/1677342686170385266/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=1677342686170385266' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1677342686170385266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1677342686170385266'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/06/entendendo-simbolos-em-ruby.html' title='Entendendo símbolos em Ruby (tradução)'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5797224620643706612</id><published>2009-06-13T16:52:00.003-03:00</published><updated>2009-06-13T16:58:51.119-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Suporte a multitouch nativo no Linux</title><content type='html'>Pessoal, esse é um post off-topic, mas eu achei muito interessante esse vídeo que mostra uma nova característica no Kernel do Linux, o suporte a multitouch.&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/DTeUbx_nnM4&amp;amp;hl=pt-br&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/DTeUbx_nnM4&amp;amp;hl=pt-br&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Abraços!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5797224620643706612?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5797224620643706612/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5797224620643706612' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5797224620643706612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5797224620643706612'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/06/suporte-multitouch-nativo-no-linux.html' title='Suporte a multitouch nativo no Linux'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2245536351476349940</id><published>2009-06-09T21:43:00.003-03:00</published><updated>2009-06-09T23:22:12.148-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails na prática'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>RnP #1 Como atribuir o endereço do site a uma action</title><content type='html'>Para iniciar a série de posts &lt;span style="font-weight: bold;"&gt;"Rails na prática"&lt;/span&gt;, vou falar sobre um assunto que foi uma das minhas primeiras dúvidas na hora de implementar um site com Rails.&lt;br /&gt;&lt;br /&gt;Ruby on Rais é um framework &lt;a href="http://pt.wikipedia.org/wiki/MVC"&gt;MVC&lt;/a&gt; (Model View Controller) e para acessar uma página geralmente o endereço é composto da seguinte forma:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;http://dominio_do_seu_site/nome_do_controller/nome_da_action&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O que acontece é que, quando estou criando um site, eu quero que o usuário tenha a opção de acessar meu site direto pelo domínio dele, por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;http://www.brunograsselli.com.br&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Como fazer, então, para que o Rails atribua o endereço de meu domínio à algum endereço reconhecido por ele?&lt;br /&gt;&lt;br /&gt;Existe um arquivo dentro do Rails que define os endereços de sua aplicação ou, como ele diz, as rotas. Esse arquivo encontrasse em &lt;span style="font-weight: bold;"&gt;config/routes.rb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Abra esse arquivo pelo seu editor de texto e digite dentro dele uma linha como, por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;map.root :controller =&gt; "posts", :action =&gt; "index"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Isso fará com que, quando eu acessar o endereço do domínio do meu site, o Rails me mostre a página que é montada pela action &lt;span style="font-weight: bold;"&gt;index&lt;/span&gt; do controller &lt;span style="font-weight: bold;"&gt;posts&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Como eu estou atribuindo à action &lt;span style="font-weight: bold;"&gt;index&lt;/span&gt;, eu poderia apenas informar o controller:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;map.root :controller =&gt; "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;posts&lt;/span&gt;"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(204, 0, 0);"&gt;Importante:&lt;/span&gt; Além de fazer isso, para que comece a funcionar você precisa também excluir o arquivo que encontrasse em &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;public&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;index&lt;/span&gt;.html&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Após excluir esse arquivo, já deve começar a funcionar.&lt;br /&gt;&lt;br /&gt;Nesse arquivo encontrasse comentado uma série de formas que você pode definir rotas para sua aplicação. Vale a pena dar uma estudada no assunto para definir endereços mais simples e intuitivos e, também, mais valorizados pelo &lt;a href="http://www.google.com/"&gt;google&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Você pode encontrar mais informações sobre o assunto em &lt;a href="http://guias.rubyonrails.pro.br/routing.html"&gt;http://guias.rubyonrails.pro.br/routing.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Espero que o texto ajude quem está começando a se aventurar no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;RoR&lt;/span&gt;, em breve continuarei com os textos da série que visa ensinar como solucionar algumas dúvidas simples que podemos ter no início do aprendizado &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Rails&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;post&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2245536351476349940?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2245536351476349940/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2245536351476349940' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2245536351476349940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2245536351476349940'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/06/rnp-1-como-atribuir-o-endereco-do-site.html' title='RnP #1 Como atribuir o endereço do site a uma action'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6613799941074908850</id><published>2009-06-07T23:21:00.003-03:00</published><updated>2009-06-07T23:39:03.688-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails na prática'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails na Prática</title><content type='html'>Desde janeiro que eu venho estudando Ruby e Ruby on Rails a fundo. Fiz um curso no começo do ano na Caelum (ótimo curso) e desde então estou apaixonado por essa linguagem e sempre que dá estou procurando algo a respeito.&lt;br /&gt;&lt;br /&gt;Apesar de estar sempre lendo livros sobre Rails (na verdade, mais Ruby do que Rails) e participando da comunidade, ainda não tinha começado a fazer nenhum projeto em Rails pra valer.&lt;br /&gt;&lt;br /&gt;Esse final de semana, finalmente, comecei meu primeiro projeto e já me deparei com uma série de dúvidas. E é por isso que venho aqui escrever para vocês.&lt;br /&gt;&lt;br /&gt;Minha proposta é, nos próximos posts, escrever a respeito de todas essas dúvidas e curiosidades que eu venho enfrentando nesse primeiro projeto. Na maioria das vezes coisas simples, que nas linguagens que estamos habituados a utilizar fazemos sem problema, mas quando vamos fazer no Rails acabamos parando pra pensar:&lt;br /&gt;&lt;br /&gt;"Putz, não havia pensado nisso. E agora, como se faz isso?"&lt;br /&gt;&lt;br /&gt;E corremos atrás do google e dos amigos nas comunidades.&lt;br /&gt;&lt;br /&gt;Toda vez que estou me deparando com uma situação como essa, estou fazendo minhas anotações para depois vir aqui falar a respeito, na série de posts que eu vou chamar de &lt;span style="font-weight: bold;"&gt;Rails na Prática (RnP)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Ainda nessa semana pretendo fazer o primeiro post sobre o tema.&lt;br /&gt;&lt;br /&gt;Espero que gostem e se tiverem sugestões por favor entrem em contato por e-mail, comentário, ou &lt;a href="http://twitter.com/grasselli"&gt;twitter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6613799941074908850?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6613799941074908850/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6613799941074908850' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6613799941074908850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6613799941074908850'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/06/rails-na-pratica.html' title='Rails na Prática'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-7521746291583914842</id><published>2009-06-06T20:01:00.003-03:00</published><updated>2009-06-06T20:17:52.665-03:00</updated><title type='text'>Link para denúncias no portal da Anatel</title><content type='html'>Recentemente eu tive alguns problemas com o serviço de internet móvel da &lt;span style="font-weight: bold;"&gt;Claro SP&lt;/span&gt;, então, durante dois dias, tentei entrar em contato com eles mas, após escolher a opção &lt;span style="font-weight: bold;"&gt;abrir reclamação&lt;/span&gt;, fiquei esperando por mais de meia hora sem ser atendido.&lt;br /&gt;&lt;br /&gt;A solução que eu tive para solucionar esse problema foi bem simples e gostaria de divulgá-la para que todos possam exercer seu direito.&lt;br /&gt;&lt;br /&gt;No portal d&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;a &lt;span style="font-weight: bold;"&gt;Anatel&lt;/span&gt; (&lt;a href="http://www.anatel.gov.br/"&gt;http://www.anatel.gov.br&lt;/a&gt;) existe um opção de &lt;a href="http://sistemas.anatel.gov.br/focus/FaleConosco/validarUsuario.asp"&gt;Atendimento Eletrônico&lt;/a&gt; (dentro do link &lt;span style="font-weight: bold;"&gt;fale conosco&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Lá você pode abrir uma denúncia contra esse tipo de serviço em operadoras de telefonia, internet, radio e tv por assinatura.&lt;br /&gt;&lt;br /&gt;Após abrir a denúncia a operadora tem 5 dias para solucionar o problema, senão é punida.&lt;br /&gt;&lt;br /&gt;Comigo funcionou perfeitamente, no dia seguinte a Claro já estava desesperada atrás de mim.&lt;br /&gt;&lt;br /&gt;Passe essa informação adiante no seu blog, twitter, etc, para melhorarmos a qualidade desse tipo de serviço.&lt;br /&gt;&lt;br /&gt;Até o próximo post,&lt;br /&gt;&lt;br /&gt;Abraços.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-7521746291583914842?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/7521746291583914842/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=7521746291583914842' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7521746291583914842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7521746291583914842'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/06/link-para-denuncias-no-portal-da-anatel.html' title='Link para denúncias no portal da Anatel'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-373425669778669974</id><published>2009-05-31T14:33:00.010-03:00</published><updated>2009-05-31T15:08:32.846-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Programa para criar diagramas no Linux</title><content type='html'>Hoje precisei criar alguns fluxogramas para o meu &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;TCC&lt;/span&gt; e, para não ter que correr atrás de instalar o Microsoft &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Visio&lt;/span&gt; na virtual &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;machine&lt;/span&gt;, procurei algum programa que fizesse o mesmo no Linux / &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Gnome&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Encontrei o &lt;a href="http://live.gnome.org/Dia"&gt;Dia&lt;/a&gt;, programa &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;open&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;source&lt;/span&gt;&lt;/span&gt; criado com a mesma &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;ideia&lt;/span&gt; do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Visio&lt;/span&gt;, que lhe permite criar uma série de diagramas.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SiLB8uZ0u7I/AAAAAAAAAM8/-ED2V5GlLr8/s1600-h/dia.png"&gt;&lt;img style="cursor: pointer; width: 171px; height: 400px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SiLB8uZ0u7I/AAAAAAAAAM8/-ED2V5GlLr8/s400/dia.png" alt="" id="BLOGGER_PHOTO_ID_5342045357007485874" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Para quem estiver precisando de um programa para isso, recomendo o Dia. Ele supriu todas as minhas necessidades na criação do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;TCC&lt;/span&gt; e, provavelmente, vai começar a me ajudar em meus &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;projetos&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Ele trabalha com diversos tipos de diagramas, inclusive os diagramas de UML, e te dá a opção de exportar o diagrama em diversos formatos de imagem, entre eles, o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;png&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Você pode instalar o Dia facilmente através do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;gerenciador&lt;/span&gt; de pacotes da sua distribuição.&lt;br /&gt;&lt;br /&gt;No &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Ubuntu&lt;/span&gt;, você pode digitar no console:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;sudo&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;apt&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;get&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;install&lt;/span&gt; dia&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ou procurar por ele no próprio &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Synaptic&lt;/span&gt; (Sistema/Administração/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;Gerenciador&lt;/span&gt; de Pacotes &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;Synaptic&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Abaixo seguem endereços para os sites do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;projeto&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://live.gnome.org/Dia"&gt;http://live.gnome.org/Dia&lt;/a&gt;&lt;br /&gt;&lt;a href="http://projects.gnome.org/dia"&gt;http://projects.gnome.org/dia&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-373425669778669974?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/373425669778669974/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=373425669778669974' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/373425669778669974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/373425669778669974'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/05/programa-para-criar-diagramas-no-linux.html' title='Programa para criar diagramas no Linux'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_CGnpveaIy_M/SiLB8uZ0u7I/AAAAAAAAAM8/-ED2V5GlLr8/s72-c/dia.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2741312658107578657</id><published>2009-05-21T21:42:00.006-03:00</published><updated>2009-05-21T22:34:30.795-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dicas de programação'/><title type='text'>Programe de forma simples</title><content type='html'>Li há uns meses atrás no livro &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;The&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Pragmatic&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Programmer&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;from&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;journeyman&lt;/span&gt; to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;master&lt;/span&gt;&lt;/span&gt; o seguinte trecho:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Programmers&lt;/span&gt; are &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;taught&lt;/span&gt; to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;comment&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;their&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;code&lt;/span&gt;: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;good&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;code&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;has&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;lots&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;of&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;comments&lt;/span&gt;. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Unfortunately&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;they&lt;/span&gt; are &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;never&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;taught&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;why&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;code&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;needs&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;comments&lt;/span&gt;: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;bad&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;code&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;requires&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;lots&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;of&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;comments&lt;/span&gt;.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;A tradução seria algo como:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Programadores são ensinados a comentar seus códigos: código bom tem um monte de comentários. Infelizmente, eles nunca são ensinados porque código precisa de comentários: código ruim requer um monte de comentários.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Lembrei deste capítulo esses dias quando minha professora de engenharia de software afirmava que código bom é código comentado.&lt;br /&gt;&lt;br /&gt;Um código bem escrito fala por si só, comentários nesse caso poderiam ser encarados até como duplicação de informação (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;DRY&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;don&lt;/span&gt;'t &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;repeat&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;yourself&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Mas o que eu chamo de código bem escrito?&lt;br /&gt;&lt;br /&gt;Nem sempre o algoritmo que resolve uma solução com menos linhas, ou até mesmo um que obtém um melhor desempenho, é a melhor solução para um determinado problema. Programação é mais do que bons algoritmos, trata também de legibilidade, utilização de padrões, código flexível e reutilizável, entre outros.&lt;br /&gt;&lt;br /&gt;Esse algoritmo com menos linhas, pode ser algo não reutilizável em situações similares. Ou um código que, por utilizar uma solução não convencional (gambiarra), pode não ser tão legível para outro programador, ou para você mesmo daqui uns meses.&lt;br /&gt;&lt;br /&gt;Eu tento sempre quando estou programando pensar em soluções simples. Na maioria das vezes eu penso em como eu faria se fosse feito manualmente e então implemento algo que siga o mesmo caminho, utilizando os benefícios que a linguagem e o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;framework&lt;/span&gt; me proporcionam.&lt;br /&gt;&lt;br /&gt;Por exemplo, vamos dizer que eu tenho uma pilha de tijolos de lego em meu sistema, e tenho que desenvolver um processo nele onde ele encontre uma quantidade determinada de tijolos de uma mesma cor. Por exemplo, eu quero que ele busque 5 tijolos vermelhos.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/ShX1d4kwJZI/AAAAAAAAAM0/uGgz_75FhKA/s1600-h/lego.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 297px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/ShX1d4kwJZI/AAAAAAAAAM0/uGgz_75FhKA/s400/lego.jpg" alt="" id="BLOGGER_PHOTO_ID_5338442827069138322" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Se eu fosse fazer manualmente, eu correria os tijolos com os olhos (utilizando a mão se necessário) verificando a cor de cada um e iria separando os vermelhos até obter a quantidade esperada. Se eu não encontrasse a quantidade necessária, sabendo que lá é o único lugar para conseguir os tijolos, alertaria a quem me pediu.&lt;br /&gt;&lt;br /&gt;Para implementar o sistema eu faria da mesma forma. Solicitaria a cor e a quantidade desejada. Correria um laço pelos tijolos disponíveis &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;peguntando&lt;/span&gt; a cada um deles qual é sua cor. Logo, a classe tijolo teria de ter um método que diz sua cor. Se encontrasse quantos eu precisasse eu retornaria a quem me pediu. Se ao chegar ao final eu não tivesse encontrado, retornaria um erro, ou &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;exceção&lt;/span&gt; (dependendo de quão comum fosse essa escassez dos tijolos - se fosse algo possível de acontecer, erro, se fosse algo que não deveria acontecer, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;exceção&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Mas, e se eu descobrisse que os tijolos vermelhos são mais leves dos que os demais e que, se eu desse uma pancada na mesa, os tijolos vermelhos seriam os únicos que pulariam acima de 20 cm de altura? Iria eu utilizar isso para desenvolver uma técnica mais rápida de conseguir os tijolos vermelhos?&lt;br /&gt;&lt;br /&gt;Provavelmente não. Ainda assim eu optaria pela primeira solução, por diversos motivos:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ela é a solução mais esperada, se alguém ler esse código com certeza vai entender do que se trata, mesmo ele não estando comentado.&lt;/li&gt;&lt;li&gt;E se um dia os tijolos azuis ficarem mais leves ou tão leves quanto os vermelhos?&lt;/li&gt;&lt;li&gt;A primeira solução funciona para qualquer tipo de tijolo, independente da cor.&lt;/li&gt;&lt;li&gt;A primeira solução, por ser simples, é mais flexível e extensível. A segunda opção, por tratar uma situação muito específica, será mais difícil de expandir ou alterar quando os usuários solicitarem. E acreditem, todo código nasce para ser expandido ou alterado futuramente. Se ainda não solicitaram isso, irão.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Precisamos sempre avaliar o código que estamos criando por diversos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;fatores&lt;/span&gt; diferentes. Muitas vezes uma melhor legibilidade vale mais do que uma pequena melhora de desempenho ou um código menor. É necessário avaliar quais são as reais prioridades no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;projeto&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Se por algum motivo você tiver que optar por uma solução não convencional, aí seria indicado deixar um comentário. Se você perceber que seu código está ficando com muitos comentários, o melhor é reavaliar se seu programa está indo na &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;direção&lt;/span&gt; correta.&lt;br /&gt;&lt;br /&gt;Uma programação de forma simples pode lhe trazer diversos benefícios, portanto fique sempre atento ao método como você está programando.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2741312658107578657?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2741312658107578657/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2741312658107578657' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2741312658107578657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2741312658107578657'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/05/programe-de-forma-simples.html' title='Programe de forma simples'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_CGnpveaIy_M/ShX1d4kwJZI/AAAAAAAAAM0/uGgz_75FhKA/s72-c/lego.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4579273385646203458</id><published>2009-05-17T11:47:00.003-03:00</published><updated>2009-05-17T12:36:35.697-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Configurar login automático no Ubuntu</title><content type='html'>Na versão anterior que eu tinha do Ubuntu eu usava a opção de login automático (Início automático de sessão), para não ter que digitar usuário e senha toda vez que ligasse o laptop, mas quando fiz o update para a versão 9.04 Jaunty Jackalope o sistema voltou  a solicitar as informações de login para iniciar.&lt;br /&gt;&lt;br /&gt;Se você teve esse mesmo problema, ou se simplesmente deseja habilitar essa opção, vá em:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sistema -&gt; Administração -&gt; Janela de início de sessão&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Vá até a aba &lt;span style="font-weight: bold;"&gt;Segurança&lt;/span&gt;, habilite o opção &lt;span style="font-weight: bold;"&gt;Habilitar início automático de sessão&lt;/span&gt; e informe o usuário que o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Ubuntu&lt;/span&gt; deverá usar para iniciar a sessão.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/ShAtlaS2D1I/AAAAAAAAAMs/2JJdMgHPJzc/s1600-h/inicio_automatico.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 372px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/ShAtlaS2D1I/AAAAAAAAAMs/2JJdMgHPJzc/s400/inicio_automatico.gif" alt="" id="BLOGGER_PHOTO_ID_5336815679170809682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;E assim o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Ubuntu&lt;/span&gt; voltará a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;efetuar&lt;/span&gt; o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;login&lt;/span&gt; automaticamente.&lt;br /&gt;&lt;br /&gt;Até mais!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4579273385646203458?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4579273385646203458/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4579273385646203458' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4579273385646203458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4579273385646203458'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/05/configurar-login-automatico-no-ubuntu.html' title='Configurar login automático no Ubuntu'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/ShAtlaS2D1I/AAAAAAAAAMs/2JJdMgHPJzc/s72-c/inicio_automatico.gif' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5294443929764133897</id><published>2009-05-13T21:26:00.003-03:00</published><updated>2009-05-13T21:34:45.925-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Disponível nova edição da Rails Magazine</title><content type='html'>Post rápido para avisar que já está disponível para download a segunda edição da revista Rails Magazine.&lt;br /&gt;&lt;br /&gt;É uma edição especial que trás a cobertura do RailsConf 2009 que aconteceu em Las Vegas.&lt;br /&gt;&lt;br /&gt;Confiram no link:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://railsmagazine.com/issues/2"&gt;http://railsmagazine.com/issues/2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[]s.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5294443929764133897?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5294443929764133897/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5294443929764133897' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5294443929764133897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5294443929764133897'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/05/disponivel-nova-edicao-da-rails.html' title='Disponível nova edição da Rails Magazine'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-1735118236616043929</id><published>2009-05-10T17:45:00.007-03:00</published><updated>2009-05-10T18:05:15.626-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Claro 3G no Ubuntu 9.04 conecta mas não navega</title><content type='html'>Depois de uma semana e meia tentando, consegui atualizar o meu Ubuntu para a nova versão 9.04.&lt;br /&gt;&lt;br /&gt;Os servidores dessa vez estavam muito congestionados.&lt;br /&gt;&lt;br /&gt;Após a instalação minha internet banda larga (Claro 3G) parou de funcionar. Ele conectava mas não acessava nenhuma página. Na versão 8.10 tinha dado algo parecido que eu arrumei adicionando a seguinte linha no final do arquivo &lt;span style="font-weight: bold;"&gt;/etc/ppp/options&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;ipcp-max-failure 30&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SgdAo8i37SI/AAAAAAAAAMk/qQZ7KWF16pE/s1600-h/gedit.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 263px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SgdAo8i37SI/AAAAAAAAAMk/qQZ7KWF16pE/s400/gedit.png" alt="" id="BLOGGER_PHOTO_ID_5334303355834985762" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Na versão 9.04, para solucionar o problema, além disso, faça o seguinte:&lt;br /&gt;&lt;br /&gt;Acesse &lt;span style="font-weight: bold;"&gt;Sistema/Preferências/Conexões de rede&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Vá até a aba &lt;span style="font-weight: bold;"&gt;Banda larga móvel&lt;/span&gt;, selecione a sua conexão e clique em &lt;span style="font-weight: bold;"&gt;editar&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SgdAALqhJ3I/AAAAAAAAAMU/Q0LpC-Re8F4/s1600-h/conexoes_de_rede.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 262px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SgdAALqhJ3I/AAAAAAAAAMU/Q0LpC-Re8F4/s400/conexoes_de_rede.png" alt="" id="BLOGGER_PHOTO_ID_5334302655518943090" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Acesse a aba &lt;span style="font-weight: bold;"&gt;Configurações IPv4 &lt;/span&gt;e no item &lt;span style="font-weight: bold;"&gt;Método&lt;/span&gt; selecione a opção &lt;span style="font-weight: bold;"&gt;Automático (PPP)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SgdAH9V2mWI/AAAAAAAAAMc/uzP2UwyQfBU/s1600-h/editando.png"&gt;&lt;img style="cursor: pointer; width: 388px; height: 400px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SgdAH9V2mWI/AAAAAAAAAMc/uzP2UwyQfBU/s400/editando.png" alt="" id="BLOGGER_PHOTO_ID_5334302789113125218" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Aqui funcionou perfeitamente após isso.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-1735118236616043929?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/1735118236616043929/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=1735118236616043929' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1735118236616043929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1735118236616043929'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/05/claro-3g-no-ubuntu-904-conecta-mas-nao.html' title='Claro 3G no Ubuntu 9.04 conecta mas não navega'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_CGnpveaIy_M/SgdAo8i37SI/AAAAAAAAAMk/qQZ7KWF16pE/s72-c/gedit.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5123935336940343675</id><published>2009-05-06T23:25:00.004-03:00</published><updated>2009-05-06T23:38:07.518-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Usando TinyMCE no Ruby on Rails</title><content type='html'>TinyMCE é um script escrito em javascript que adiciona aos seus campos TEXTAREA, dentre outros elementos do HTML, características avançadas similiares às de um editor de texto, como o Microsoft Word.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SfeYTczO_1I/AAAAAAAAAK0/0-MEpCjGaDk/s1600-h/tinymce01.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 147px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SfeYTczO_1I/AAAAAAAAAK0/0-MEpCjGaDk/s400/tinymce01.png" alt="" id="BLOGGER_PHOTO_ID_5329896143932292946" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Recentemente precisei utilizar um recurso como este em meu projeto de conclusão do curso na faculdade e escolhi o TinyMCE para isso. Encontrei algumas opções para configurá-lo no Rails através de Ruby Gems ou Plugins, mas, não sei se foi por incompatibilidade da minha aplicação ou por falta de conhecimento meu na hora de configurar, não consegui colocar em funcionamento.&lt;br /&gt;&lt;br /&gt;Então entrei no site oficial do script (&lt;a href="http://tinymce.moxiecode.com/"&gt;http://tinymce.moxiecode.com&lt;/a&gt;) e procurei a respeito de como configurá-lo manualmente. O procedimento para isto é extremamente simples, vou descrever a seguir.&lt;br /&gt;&lt;br /&gt;Para começar irei criar uma aplicação de Rails simples utilizando scaffold, para que vocês possam acompanhar na prática o procedimento e para não fugirmos muito do escopo do post.&lt;br /&gt;&lt;br /&gt;Sendo assim, abrirei o console e digitarei os seguintes comandos no diretório onde costumo gravar meus projetos de RoR (Ruby on Rails):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rails notes -d mysql&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Nosso projeto de exemplo será um programa para criação de anotações, por isso o nome "notes" e, como utilizo banco de dados MySQL, utilizei os parâmetros "-d mysql".&lt;br /&gt;&lt;br /&gt;O comando acima criou nosso projeto, agora vou configurar o arquivo config/database.yml para alterar a senha do banco de dados. Para isso estou utilizando o editor de texto gvim, mas você pode escolher o que achar melhor.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;cd notes&lt;br /&gt;gvim config/database.yml&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SfedX6d0ipI/AAAAAAAAAK8/OAVgVfnn7wE/s1600-h/databaseyml.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 265px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SfedX6d0ipI/AAAAAAAAAK8/OAVgVfnn7wE/s400/databaseyml.png" alt="" id="BLOGGER_PHOTO_ID_5329901718173158034" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Agora vamos criar um model chamado note, que terá um título e um texto de corpo. Como disse, utilizarei scaffold para poupar tempo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;script/generate scaffold note title:string body:text&lt;br /&gt;rake db:create&lt;br /&gt;rake db:migrate&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Se você quiser testar para ver se tudo está conforme o planejado, inicie o servidor:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;script/server&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E acesse o endereço &lt;a href="http://localhost:3000/notes/new"&gt;http://localhost:3000/notes/new&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Deve estar como na figura abaixo:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/Sfegenmwx9I/AAAAAAAAALE/4juLTedAom4/s1600-h/scaffold.png"&gt;&lt;img style="cursor: pointer; width: 253px; height: 400px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/Sfegenmwx9I/AAAAAAAAALE/4juLTedAom4/s400/scaffold.png" alt="" id="BLOGGER_PHOTO_ID_5329905131904354258" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;A idéia agora é aplicar o &lt;span style="font-weight: bold;"&gt;TinyMCE&lt;/span&gt; a essa &lt;span&gt;textarea&lt;/span&gt; da &lt;span&gt;view&lt;/span&gt; da figura acima (&lt;span style="font-weight: bold;"&gt;new.html.erb&lt;/span&gt;). Então vamos iniciar a configuração do script em si.&lt;br /&gt;&lt;br /&gt;Primeiro de tudo você deve baixar o script no site:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://tinymce.moxiecode.com/download.php"&gt;http://tinymce.moxiecode.com/download.php&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hoje, 28 de abril de 2009, a versão atual é &lt;a href="http://prdownloads.sourceforge.net/tinymce/tinymce_3_2_3.zip?download"&gt;tinymce_3_2_3.zip&lt;/a&gt; (main package).&lt;br /&gt;&lt;br /&gt;Após baixar o arquivo descompacte-o e abra o seu conteúdo.&lt;br /&gt;Dentro do diretório jscripts existe um diretório chamado tiny_mce.&lt;br /&gt;&lt;br /&gt;Mova esse diretório para seu_projeto/public/javascripts&lt;br /&gt;&lt;br /&gt;Deve ficar assim:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;/public/javascripts/tiny_mce&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Feito isso abra a view que iremos aplicar o script (&lt;span style="font-weight: bold;"&gt;app/views/notes/new.html.erb&lt;/span&gt;) em seu editor de textos preferido. No meu caso utilizarei o gvim de novo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;gvim app/views/notes/new.html.erb&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Primeiramente vamos carregar o script em nossa view. Para isso, ao invés de utilizarmos as tags do html diretamente, utilizaremos os helpers do Rails.&lt;br /&gt;&lt;br /&gt;Nesse caso vamos utilizar o método &lt;span style="font-weight: bold;"&gt;javascript_include_tag&lt;/span&gt;, que recebe o nome do javascript como parâmetro.&lt;br /&gt;&lt;br /&gt;Então, após abrir a view, adicione logo no início do arquivo a seguinte linha:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;%= javascript_include_tag 'tiny_mce/tiny_mce.js' %&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Deve ficar assim:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SfenbcHsdPI/AAAAAAAAALU/Xr9H57BsEL4/s1600-h/javascript_include_tag.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 265px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SfenbcHsdPI/AAAAAAAAALU/Xr9H57BsEL4/s400/javascript_include_tag.png" alt="" id="BLOGGER_PHOTO_ID_5329912773863044338" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;E agora vamos adicionar um trecho de javascript que irá configurar como nossa textarea deve ser exibida (que opções de formatação deve conter, etc).&lt;br /&gt;&lt;br /&gt;No próprio site do script contém vários exemplos de configurações prontos, assim como uma API e documentação sobre o assunto. Acesse:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://tinymce.moxiecode.com/examples/full.php"&gt;http://tinymce.moxiecode.com/examples/full.php &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Você pode escolher um dos exemplos e clicar em &lt;span style="font-weight: bold;"&gt;"View Source"&lt;/span&gt; para visualizar o código fonte.&lt;br /&gt;&lt;br /&gt;Para nosso exemplo eu utilizarei um exemplo pronto do site denominado &lt;span style="font-weight: bold;"&gt;"Simple"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Para criar tags de javascript em nossa view utilizarei o método&lt;span style="font-weight: bold;"&gt; javascript_tag&lt;/span&gt; e colocarei o código retirado do site do TinyMCE dentro dele, ficará assim (pode ser logo após a útima linha que digitamos no arquivo):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;% javascript_tag do     tinyMCE.init({                 mode : "textareas", theme : "simple"         }); end %&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/Sferm--er2I/AAAAAAAAALc/wsZHXwcpRlA/s1600-h/javascript_tag.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 265px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/Sferm--er2I/AAAAAAAAALc/wsZHXwcpRlA/s400/javascript_tag.png" alt="" id="BLOGGER_PHOTO_ID_5329917370244706146" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Execute o servidor para ver o resultado, deve ter ficado assim:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SfesezVX4wI/AAAAAAAAALs/1UcqwPItVz0/s1600-h/resultado.png"&gt;&lt;img style="cursor: pointer; width: 249px; height: 400px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SfesezVX4wI/AAAAAAAAALs/1UcqwPItVz0/s400/resultado.png" alt="" id="BLOGGER_PHOTO_ID_5329918329192178434" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Eu utilizei a opção de configuração mais simples do TinyMCE, para poupar o código do exemplo. Mas existem muitas outras opções com mais recursos no site de exemplos, cuja dificuldade para a configuração é exatamente a mesma do exemplo.&lt;br /&gt;&lt;br /&gt;O script faz com que, após digitar o texto formatado na textarea, ela chegue na action do controller com sua formatação já convertida para as respectivas tags de HTML.&lt;br /&gt;&lt;br /&gt;Apenas mais um último detalhe: se você entrar agora na parte de visualização dessa anotação que cadastramos, perceberá que ela não aparece formatada de acordo com o que cadastramos, as tags htmls são exibidas na tela, ao invés da formatação.&lt;br /&gt;&lt;br /&gt;Vide imagem:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SgJEUSHXRsI/AAAAAAAAAL0/pMu1eVRTqnk/s1600-h/view_com_erro.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 370px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SgJEUSHXRsI/AAAAAAAAAL0/pMu1eVRTqnk/s400/view_com_erro.png" alt="" id="BLOGGER_PHOTO_ID_5332900024010884802" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Isso ocorre porque o scaffold criou as views utilizando o método "h" para imprimir a informação no navegador.&lt;br /&gt;&lt;br /&gt;Veja a linha 8 da imagem (arquivo app/views/notes/show.html.erb):&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SgJFSrfFYUI/AAAAAAAAAL8/crIlfQmmnvA/s1600-h/codigo_com_h.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 265px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SgJFSrfFYUI/AAAAAAAAAL8/crIlfQmmnvA/s400/codigo_com_h.png" alt="" id="BLOGGER_PHOTO_ID_5332901095973151042" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Para corrigir isso basta tirarmos o método "h", como na figura:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SgJFS6ECjbI/AAAAAAAAAME/KmuffjsOlXw/s1600-h/codigo_sem_h.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 265px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SgJFS6ECjbI/AAAAAAAAAME/KmuffjsOlXw/s400/codigo_sem_h.png" alt="" id="BLOGGER_PHOTO_ID_5332901099886251442" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;E o resultado será:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SgJFS91caLI/AAAAAAAAAMM/SSjXmqWDG_A/s1600-h/tela_funcionando.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 370px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SgJFS91caLI/AAAAAAAAAMM/SSjXmqWDG_A/s400/tela_funcionando.png" alt="" id="BLOGGER_PHOTO_ID_5332901100898773170" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;E com isso temos nossa pequena aplicação funcionando. Espero que o exemplo tenha ajudado a entender a configuração.&lt;br /&gt;&lt;br /&gt;Qualquer dúvida estou a disposição no e-mail, &lt;a href="http://twitter.com/grasselli"&gt;twitter&lt;/a&gt; ou aqui nos comentários do blog.&lt;br /&gt;&lt;br /&gt;Gostaria de agradecer ao &lt;a href="http://www.rafaelrosafu.com/"&gt;Rafael Rosa Fu&lt;/a&gt; e ao &lt;a href="http://fabiokung.com/"&gt;Fábio Kung&lt;/a&gt; por tirar as dúvidas que eu tinha em relação a esse post e também pela ajuda que eles sempre me dão em todos os meus testes com o Rails.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post!&lt;br /&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5123935336940343675?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5123935336940343675/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5123935336940343675' title='7 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5123935336940343675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5123935336940343675'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/05/usando-tinymce-no-ruby-on-rails.html' title='Usando TinyMCE no Ruby on Rails'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/SfeYTczO_1I/AAAAAAAAAK0/0-MEpCjGaDk/s72-c/tinymce01.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2944339503410094976</id><published>2009-04-23T22:57:00.003-03:00</published><updated>2009-04-23T23:08:28.526-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Nova versão do Ubuntu, 9.04 Jaunty Jackalope, lançada!</title><content type='html'>Já está disponível para &lt;a href="http://www.ubuntu.com/"&gt;download&lt;/a&gt; ou update a nova versão do Ubuntu, Jaunty Jackalope.&lt;br /&gt;&lt;br /&gt;Eu estava desatualizado quando ao desenvolvimento dessa nova versão e o sistema de updates do Ubuntu me pegou de surpresa hoje.&lt;br /&gt;&lt;br /&gt;De novo eles cumpriram o prazo estipulado, que era de que a nova versão 9.04 sairia em abril de 2009.&lt;br /&gt;&lt;br /&gt;Confiram em:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ubuntu.com/"&gt;http://www.ubuntu.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Abraços!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2944339503410094976?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2944339503410094976/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2944339503410094976' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2944339503410094976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2944339503410094976'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/04/nova-versao-do-ubuntu-904-jaunty.html' title='Nova versão do Ubuntu, 9.04 Jaunty Jackalope, lançada!'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8595989288790890109</id><published>2009-04-21T11:26:00.003-03:00</published><updated>2009-04-21T11:37:34.322-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='editores de texto'/><title type='text'>Vim + Ruby on Rails</title><content type='html'>Acabo de ler no blog do &lt;a href="http://patrickespake.wordpress.com/"&gt;Patrick Espake&lt;/a&gt; um post muito interessante sobre como adaptar e utilizar o editor de texto &lt;span style="font-weight: bold;"&gt;Vim&lt;/span&gt; do Linux para trabalhar com &lt;span style="font-weight: bold;"&gt;Ruby on Rails&lt;/span&gt; de forma totalmente integrada.&lt;br /&gt;&lt;br /&gt;Estava procurando sobre esse assunto ainda esse domingo, mas os artigos que havia encontrado não estavam funcionando completamente quando eu testava. O do Patrick ficou bem legal e estou seriamente pensando em começar a usar o Vim, no lugar do Gedit + Gmate.&lt;br /&gt;&lt;br /&gt;Fica aí a dica, acessem o link do post, abaixo, e conheçam mais uma boa alternativa para ambiente de desenvolvimento Ruby on Rails.&lt;br /&gt;&lt;a href="http://patrickespake.wordpress.com/2009/04/21/usando-o-vim-para-programar-em-ruby-on-rails/"&gt;&lt;br /&gt;http://patrickespake.wordpress.com/2009/04/21/usando-o-vim-para-programar-em-ruby-on-rails/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Queria aproveitar pra falar que agora também estou no Twitter. Ainda estou aprendendo como funciona mas parece uma rede bem interessante. Quem quiser me encontrar lá segue o link:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://twitter.com/grasselli"&gt;http://twitter.com/grasselli&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;Abraços!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8595989288790890109?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8595989288790890109/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8595989288790890109' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8595989288790890109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8595989288790890109'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/04/vim-ruby-on-rails.html' title='Vim + Ruby on Rails'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-3452889239353430869</id><published>2009-04-19T16:01:00.006-03:00</published><updated>2009-04-19T16:09:16.770-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Teclas de atalho do Gnome</title><content type='html'>Hoje vou fazer um post rápido sobre as teclas de atalho do Gnome. Eu uso Gnome em meu computador pessoal (Ubuntu 8.10) e, no meu serviço, utilizo Windows XP (não por opção). No serviço eu tenho costume de utilizar o atalho "botão do windows + M" para ir direto para a área de trabalho independentemente do número de janelas que estiverem abertas no micro.&lt;br /&gt;&lt;br /&gt;Sempre pensei em pesquisar por um atalho semelhante no Gnome mas até hoje nunca tinha ido atrás. Hoje enquanto escrevia um aplicativo pequeno em Ruby para automatizar umas tarefas no meu micro, tomei coragem e descobri no site do &lt;a href="http://gnome.org/"&gt;gnome.org&lt;/a&gt; que o atalho &lt;b&gt;CTRL + ALT + D&lt;/b&gt; faz praticamente o mesmo efeito.&lt;br /&gt;&lt;br /&gt;Pressionando &lt;b&gt;CTRL + ALT + D&lt;/b&gt; uma vez você minimiza todos as janelas abertas e visualiza a área de trabalho, pressionando de novo você restaura as janelas novamente.&lt;br /&gt;&lt;br /&gt;Você pode encontrar todos os atalhos no Gnome no endereço:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://library.gnome.org/users/user-guide/stable/keyboard-skills.html.pt_BR"&gt;http://library.gnome.org/users/user-guide/stable/keyboard-skills.html.pt_BR&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Vou listar abaixo os que mais utilizo:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ALT + F2&lt;/b&gt;&lt;br /&gt;Abre uma janela onde você entra com o nome do aplicativo que deseja executar. Semelhante ao Iniciar -&amp;gt; Executar do Windows (botão do Windows + R).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;CTRL + ALT + SETAS&lt;/b&gt;&lt;br /&gt;Intercala entre as áreas de trabalho.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;CTRL + ALT + SHIFT + SETAS&lt;/b&gt;&lt;br /&gt;Envia a janela em foco para outra área de trabalho.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;CTRL + ALT + D&lt;/b&gt;&lt;br /&gt;Minimiza as janelas ativas.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;CTRL + L&lt;/b&gt;&lt;br /&gt;Bloqueia o computador.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;ALT + TAB&lt;/b&gt;&lt;br /&gt;Intercala entre as janelas abertas.&lt;br /&gt;&lt;br /&gt;Espero que a dica ajude quem estiver procurando pelo assunto. Usar teclas de atalho sempre trás mais agilidade aos processos.&lt;br /&gt;&lt;br /&gt;Estou usando este post também para testar o serviço de postagem por e-mail do Blogger.&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-3452889239353430869?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/3452889239353430869/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=3452889239353430869' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3452889239353430869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3452889239353430869'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/04/teclas-de-atalho-do-gnome.html' title='Teclas de atalho do Gnome'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5150985256585908838</id><published>2009-04-10T12:29:00.006-03:00</published><updated>2009-04-10T12:52:40.252-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='livros'/><title type='text'>O Guia (comovente) de Ruby do Why</title><content type='html'>O Carlos Brando anunciou no &lt;a href="http://www.nomedojogo.com/"&gt;Nome do jogo&lt;/a&gt; o lançamento da versão 1.0 da tradução do livro &lt;span style="font-weight: bold;"&gt;Why's Poignant Guide to Ruby&lt;/span&gt;, depois de quase um ano de trabalho.&lt;br /&gt;&lt;br /&gt;Ainda não o li pois estou terminando a leitura do &lt;span style="font-weight: bold;"&gt;The Pragmatic Programmer&lt;/span&gt;, livro que com certeza vou indicar aqui no blog após concluir. Mas confio plenamente na qualidade de um livro escrito pelo Why (criador do &lt;a href="http://shoooes.net/"&gt;Shoes&lt;/a&gt;) e indicado pelo Carlos Brando e toda a comunidade Ruby.&lt;br /&gt;&lt;br /&gt;Segue abaixo link para o livro, que pode ser lido gratuitamente pela internet:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://why.nomedojogo.com/"&gt;http://why.nomedojogo.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;E o link para o post original no Nome do jogo:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.nomedojogo.com/2009/04/09/o-comovente-guia-de-ruby-do-why/"&gt;http://www.nomedojogo.com/2009/04/09/o-comovente-guia-de-ruby-do-why&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;E para o livro original em inglês, que também pode ser lido gratuitamente:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://poignantguide.net/ruby/"&gt;http://poignantguide.net/ruby&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[]s e até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5150985256585908838?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5150985256585908838/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5150985256585908838' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5150985256585908838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5150985256585908838'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/04/o-guia-comovente-de-ruby-do-why.html' title='O Guia (comovente) de Ruby do Why'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8373125924515361301</id><published>2009-04-07T22:16:00.006-03:00</published><updated>2009-04-07T22:58:37.037-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='evento'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Avaliação Ruby + Rails no Mundo Real 2009</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/Sdv-3kdNlcI/AAAAAAAAAKI/xHjMz93xvRY/s1600-h/IMG_1693.JPG"&gt;&lt;img style="cursor: pointer; width: 400px; height: 267px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/Sdv-3kdNlcI/AAAAAAAAAKI/xHjMz93xvRY/s400/IMG_1693.JPG" alt="" id="BLOGGER_PHOTO_ID_5322127615300834754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Sábado passado, dia 4, aconteceu aqui em São Paulo o evento &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Ruby&lt;/span&gt; + &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Rails&lt;/span&gt; no Mundo Real 2009, organizado pelo pessoal da &lt;a href="http://www.guru-sp.com/"&gt;GURU-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;SP&lt;/span&gt;&lt;/a&gt; com a ajuda da Tempo Real Eventos, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Caelum&lt;/span&gt;, entre outros.&lt;br /&gt;&lt;br /&gt;Passei por aqui para publicar minha opinião em relação ao evento, ainda que um pouco atrasado.&lt;br /&gt;&lt;br /&gt;O público do evento surpreendeu em quantidade e qualidade. Segundo o que o próprio Marcelo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Castellani&lt;/span&gt; disse no começo da apresentação, eles estavam contando com bem menos gente quando estavam imaginando o evento há uns meses atrás. Não sei o número ao certo mas arrisco dizer que teve em torno de 150 congressistas.&lt;br /&gt;&lt;br /&gt;Gostei muito de todas as palestras apresentadas, mas em especial a do &lt;a href="http://nomedojogo.com/"&gt;Carlos Brando&lt;/a&gt; falando sobre testes, a do Rodrigo Franco falando sobre como trabalhar com clientes do exterior e a do &lt;a href="http://fabiokung.com/"&gt;Fabio &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Kung&lt;/span&gt;&lt;/a&gt; sobre reflection e &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;metaprogramação&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Acredito que em breve os vídeos com as palestras do evento estarão disponíveis na web, vocês podem verificar no site do &lt;a href="http://www.guru-sp.com/"&gt;GURU-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;SP&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A imagem no topo do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;post&lt;/span&gt; eu roubei do álbum do Hugo Borges sobre o evento (fim da palestra do Carlos Brando):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.com/hugo.borges/RubyRailsNoMundoReal"&gt;http://picasaweb.google.com/hugo.borges/RubyRailsNoMundoReal&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Resumindo, o evento foi muito bom, valeu a pena, e para os próximos fica o conselho: não faltem.&lt;br /&gt;&lt;br /&gt;Abraços a todos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8373125924515361301?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8373125924515361301/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8373125924515361301' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8373125924515361301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8373125924515361301'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/04/avaliacao-ruby-rails-no-mundo-real-2009.html' title='Avaliação Ruby + Rails no Mundo Real 2009'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/Sdv-3kdNlcI/AAAAAAAAAKI/xHjMz93xvRY/s72-c/IMG_1693.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2449527904453131037</id><published>2009-04-02T22:21:00.005-03:00</published><updated>2009-04-02T22:38:02.218-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Concorra a dois workshops mão na massa Ruby e Rails Tempo Real</title><content type='html'>Saudações a todos,&lt;br /&gt;&lt;br /&gt;Nos últimos dias não estou conseguindo postar muito no blog pois ando meio ocupado com serviço + tcc + um freelance que está me matando mas já estou quase acabando! Espero muito em breve voltar com gás total para o blog, estou cheio de idéias de posts interessantes, especialmente sobre Ruby e Rails e, se tudo der certo, estarei criando novas vídeo aulas também.&lt;br /&gt;&lt;br /&gt;Hoje vim aqui para divulgar mais uma iniciativa muito interessante do blog &lt;a href="http://www.rubyinside.com.br/"&gt;Ruby Inside Brasil&lt;/a&gt;, e também para participar da promoção deles =)&lt;br /&gt;&lt;br /&gt;O Ruby Inside Brasil estará sorteando dois cursos inteiramente gratuitos. Um sobre Ruby e outro sobre Rails, que acontecerão nos dias 23 e 30 de maio, respectivamente.&lt;br /&gt;&lt;br /&gt;Para concorrer basta ajudar a divulgar a promoção em seu blog ou &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Segue link para o post original:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rubyinside.com.br/concorra-a-dois-workshops-mao-na-massa-ruby-e-rails-tempo-real-885"&gt;http://www.rubyinside.com.br/concorra-a-dois-workshops-mao-na-massa-ruby-e-rails-tempo-real-885&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;E vale lembrar que este sábado, dia 4, estará acontecendo o &lt;a href="http://www.rubyinside.com.br/ruby-e-rails-no-mundo-real-2009-evento-em-sao-paulo-808"&gt;Ruby + Rails no Mundo Real 2009&lt;/a&gt;, encontro vocês lá!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2449527904453131037?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2449527904453131037/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2449527904453131037' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2449527904453131037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2449527904453131037'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/04/concorra-dois-workshops-mao-na-massa.html' title='Concorra a dois workshops mão na massa Ruby e Rails Tempo Real'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5046117305387282544</id><published>2009-03-16T23:16:00.003-03:00</published><updated>2009-03-16T23:21:56.114-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails 2.3 lançado</title><content type='html'>Post rápido:&lt;br /&gt;&lt;br /&gt;Lançada a nova versão do Rails, confira as novidades em:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://guides.rubyonrails.org/2_3_release_notes.html"&gt;http://guides.rubyonrails.org/2_3_release_notes.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Mais detalhes também no blog do &lt;a href="http://www.akitaonrails.com/"&gt;Akita&lt;/a&gt; (em português):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.akitaonrails.com/2009/03/14/rails-2-3-amanha"&gt;http://www.akitaonrails.com/2009/03/14/rails-2-3-amanha&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para atualizar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo gem update rails&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Até o próximo post!&lt;br /&gt;&lt;br /&gt;[]s.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5046117305387282544?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5046117305387282544/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5046117305387282544' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5046117305387282544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5046117305387282544'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/03/rails-23-lancado.html' title='Rails 2.3 lançado'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2202874576061989213</id><published>2009-03-15T17:43:00.003-03:00</published><updated>2009-03-15T18:04:12.763-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails Magazine</title><content type='html'>&lt;a href="http://railsmagazine.com/"&gt;&lt;img src="http://railsmagazine.com/images/ticker/railsmagazine1.jpg" alt="Rails Magazine" style="border: medium none ;" width="120" height="120" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hoje estou aqui para ajudar a divulgar uma iniciativa que conheci na última semana, a revista &lt;a href="http://railsmagazine.com/"&gt;Rails Magazine&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;É uma revista escrita periodicamente por profissionais e entusiastas de Ruby on Rails, com versão em PDF gratuita disponível na internet.&lt;br /&gt;&lt;br /&gt;Confira a primeira edição em &lt;a href="http://railsmagazine.com/issues/1"&gt;http://railsmagazine.com/issues/1&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Essa é mais uma bela iniciativa da comunidade Ruby e Rails. Se você ainda não conhece a linguagem &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt; ou o framework web &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;, não perca tempo!&lt;br /&gt;&lt;br /&gt;Segue abaixo alguns links que podem te ajudar num primeiro contato:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-i"&gt;http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-i&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-ii"&gt;http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-ii&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-iii"&gt;http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-iii&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://railscasts.com/"&gt;http://railscasts.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://guides.rails.info/"&gt;http://guides.rails.info&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Comunidades:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://groups.google.com.br/group/rails-br"&gt;http://groups.google.com.br/group/rails-br&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://rubyonbr.org/"&gt;http://rubyonbr.org&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2202874576061989213?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2202874576061989213/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2202874576061989213' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2202874576061989213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2202874576061989213'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/03/rails-magazine.html' title='Rails Magazine'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-7631630618150978507</id><published>2009-03-09T23:08:00.005-03:00</published><updated>2009-03-09T23:19:26.004-03:00</updated><title type='text'>Citações sobre especificações</title><content type='html'>&lt;blockquote&gt;Especificações inúteis&lt;br /&gt;&lt;br /&gt;Uma “especificação” é um documento quase que completamente inútil. Eu nunca vi uma especificação detalhada o suficiente para que seja útil e precisa ao mesmo tempo.&lt;br /&gt;&lt;br /&gt;E eu já vi muito lixo construído com base em especificações. Desenvolver com base em especificações é a pior maneira de se escrever software, pois por definição, trata-se de programar para satisfazer uma teoria, não a realidade.&lt;br /&gt;&lt;br /&gt;—&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Linus&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Torvalds&lt;/span&gt;, Criador do Linux (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;from&lt;/span&gt;: Linux: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Linus&lt;/span&gt; Sobre Especificações)&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Enfrente os “atrasadores de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;projeto&lt;/span&gt;”&lt;br /&gt;&lt;br /&gt;Eu cheguei à conclusão de que muitas das pessoas que insistiam em uma lista extensiva de requisitos antes de começar qualquer &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;design&lt;/span&gt; tratavam-se de meros “atrasadores” tentando &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;frear&lt;/span&gt; o processo (e que geralmente estas pessoas não tinham nada a contribuir no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;design&lt;/span&gt;, nem qualquer &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;idéia&lt;/span&gt; inovadora para compartilhar).&lt;br /&gt;&lt;br /&gt;Todo nosso melhor trabalho foi feito com alguns conceitos na cabeça sobre melhorar o site, alguns protótipos rápidos (estáticos), pequenas alterações no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;design&lt;/span&gt; e, enfim, com a construção de um protótipo funcional com dados reais. Após nos prepararmos com esse protótipo, geralmente tínhamos um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;projeto&lt;/span&gt; real em curso e um bom resultado.&lt;br /&gt;&lt;br /&gt;—Mark &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Gallagher&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;desenvolvedor&lt;/span&gt; de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;intranets&lt;/span&gt; corporativas (de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;Signal&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;vs&lt;/span&gt;. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;Noise&lt;/span&gt;)&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Ambos os textos foram retirados do livro &lt;a href="http://gettingreal.37signals.com/GR_por.php"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Getting&lt;/span&gt; Real&lt;/a&gt;, da 37&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;signals&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-7631630618150978507?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/7631630618150978507/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=7631630618150978507' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7631630618150978507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7631630618150978507'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/03/citacoes-sobre-especificacoes.html' title='Citações sobre especificações'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-7235640276921220733</id><published>2009-03-08T20:27:00.004-03:00</published><updated>2009-03-08T23:22:32.067-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='orientação a objetos'/><title type='text'>Ruby: getters e setters</title><content type='html'>Hoje vou falar um pouco a respeito de variáveis de instância em classes no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Ruby&lt;/span&gt; e seus métodos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;de acesso&lt;/span&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;No &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Ruby&lt;/span&gt;, diferentemente do Java, todas as variáveis de instância tem controle de acesso &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;private&lt;/span&gt;&lt;/span&gt;, ou seja, só são acessíveis (escrita ou leitura) &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;diretamente&lt;/span&gt; para os métodos dentro da própria classe.&lt;br /&gt;&lt;br /&gt;Para explicar melhor o porque isso é uma boa característica da linguagem, vou falar a respeito de acoplamento entre classes.&lt;br /&gt;&lt;br /&gt;Em orientação a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;objetos&lt;/span&gt; falamos que acoplamento entre classes é o nível em que uma classe tem acesso aos dados de outra. O ideal é que as classes tenham baixo &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;acoplamento&lt;/span&gt; entre si, isso é, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;acessem&lt;/span&gt; as variáveis das outras classes apenas &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_9"&gt;através&lt;/span&gt; dos métodos disponíveis por ela (encapsulamento).&lt;br /&gt;&lt;br /&gt;Vou dar um exemplo de uma relação de classes com alto acoplamento (característica não recomendada) em Java:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SbMCJnnKDdI/AAAAAAAAAIY/KoCSEAttubM/s1600-h/a_errado.png"&gt;&lt;img style="cursor: pointer; width: 228px; height: 84px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SbMCJnnKDdI/AAAAAAAAAIY/KoCSEAttubM/s400/a_errado.png" alt="" id="BLOGGER_PHOTO_ID_5310590749875244498" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SbMCR91MykI/AAAAAAAAAIg/mCJlGgyJoPs/s1600-h/b_errado.png"&gt;&lt;img style="cursor: pointer; width: 245px; height: 143px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SbMCR91MykI/AAAAAAAAAIg/mCJlGgyJoPs/s400/b_errado.png" alt="" id="BLOGGER_PHOTO_ID_5310590893278677570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Nesse exemplo temos a classe A e a classe B. A classe B contém um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;objeto&lt;/span&gt; do tipo A.&lt;br /&gt;&lt;br /&gt;Note na &lt;span style="font-weight: bold;"&gt;linha 6&lt;/span&gt; da classe B que ela &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;acessa&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;diretamente&lt;/span&gt; a variável de instância &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;name&lt;/span&gt;&lt;/span&gt; da classe A, uma vez que ela tem nível de acesso &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;public&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Esse tipo de relacionamento pode vir a trazer problemas futuramente, especialmente para a classe B, caso a classe A troque o nome da variável de instância &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;name&lt;/span&gt;&lt;/span&gt;, ou algo do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;gênero&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;O recomendado nesse caso seria que a variável &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;name&lt;/span&gt;&lt;/span&gt; tivesse nível de acesso &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;private&lt;/span&gt;&lt;/span&gt; e a classe disponibilizasse métodos para que classes externas &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;acessem&lt;/span&gt; essa variável.&lt;br /&gt;&lt;br /&gt;Como no exemplo abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SbMFCgRgQ9I/AAAAAAAAAIo/2CSBfti_b2I/s1600-h/a_certo.png"&gt;&lt;img style="cursor: pointer; width: 338px; height: 194px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SbMFCgRgQ9I/AAAAAAAAAIo/2CSBfti_b2I/s400/a_certo.png" alt="" id="BLOGGER_PHOTO_ID_5310593926181176274" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SbMFLTj-KCI/AAAAAAAAAIw/ueyxlEFh7TI/s1600-h/b_certo.png"&gt;&lt;img style="cursor: pointer; width: 253px; height: 142px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SbMFLTj-KCI/AAAAAAAAAIw/ueyxlEFh7TI/s400/b_certo.png" alt="" id="BLOGGER_PHOTO_ID_5310594077387794466" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dessa vez a classe B utiliza o método &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;setName&lt;/span&gt;&lt;/span&gt; da classe A para alterar a informação desejada. Dessa forma a classe A pode alterar sua lógica interna futuramente, sem precisar se preocupar com as classes que se relacionam com ela, portanto que ela mantenha os métodos &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;getName&lt;/span&gt;&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;setName&lt;/span&gt;&lt;/span&gt; funcionando &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;corretamente&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Isso é um exemplo de baixo acoplamento entre classes, e essa é a boa prática.&lt;br /&gt;&lt;br /&gt;Como eu estava dizendo, no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;Ruby&lt;/span&gt; as variáveis de instância são sempre &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;privates&lt;/span&gt;, o que nos força a trabalhar da forma certa, fornecendo métodos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;getters&lt;/span&gt; e &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;setters&lt;/span&gt; para &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;interação&lt;/span&gt; com outras classes.&lt;br /&gt;&lt;br /&gt;Na verdade existem métodos como o &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;instance&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;variable&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;get&lt;/span&gt;&lt;/span&gt;, que retorna o valor de uma variável de &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_32"&gt;instância&lt;/span&gt;, mas métodos como esse só devem ser usados em caso de extrema necessidade. Para o nosso texto, vamos utilizar os métodos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;getters&lt;/span&gt; e &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;setters&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Então toda vez que eu criar uma classe tenho que construir métodos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;getters&lt;/span&gt; e &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;setters&lt;/span&gt; para cada uma das variáveis de &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_37"&gt;instância&lt;/span&gt; que eu desejar deixar disponível para leitura ou escrita por outras classes?&lt;br /&gt;&lt;br /&gt;Na teoria sim, mas o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;Ruby&lt;/span&gt; possui alguns métodos que nos ajudam bastante para esse tipo de tarefa, são eles : &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;accessor&lt;/span&gt;&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;reader&lt;/span&gt;&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;writer&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Por exemplo, vou criar uma classe &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;User&lt;/span&gt;&lt;/span&gt;, dessa vez em &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;Ruby&lt;/span&gt;, que possua as variáveis de instância &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;name&lt;/span&gt;&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;age&lt;/span&gt;, as quais eu vou permitir que qualquer outra classe leia e altere seus valores (portanto vou criar métodos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;getters&lt;/span&gt; e &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;setters&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SbRHXV83owI/AAAAAAAAAI4/xbL1udV9sOw/s1600-h/class01.png"&gt;&lt;img style="cursor: pointer; width: 268px; height: 289px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SbRHXV83owI/AAAAAAAAAI4/xbL1udV9sOw/s400/class01.png" alt="" id="BLOGGER_PHOTO_ID_5310948326931669762" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;acessar&lt;/span&gt; os dados das variáveis de instância de um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;objeto&lt;/span&gt; dessa classe seria dessa forma:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SbRHXlE-H0I/AAAAAAAAAJA/Z2Bsq5fdttE/s1600-h/code01.png"&gt;&lt;img style="cursor: pointer; width: 197px; height: 57px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SbRHXlE-H0I/AAAAAAAAAJA/Z2Bsq5fdttE/s400/code01.png" alt="" id="BLOGGER_PHOTO_ID_5310948330992181058" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Por enquanto lembra um pouco o Java, certo?&lt;br /&gt;&lt;br /&gt;Agora vamos usar uma técnica bem interessante. Vamos nomear os métodos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;getters&lt;/span&gt; com o mesmo nome da variável e os métodos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;setters&lt;/span&gt; com o nome seguido de um sinal de igual (=), veja o exemplo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SbRINwMBMWI/AAAAAAAAAJI/eBo9JytHr90/s1600-h/class02.png"&gt;&lt;img style="cursor: pointer; width: 266px; height: 289px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SbRINwMBMWI/AAAAAAAAAJI/eBo9JytHr90/s400/class02.png" alt="" id="BLOGGER_PHOTO_ID_5310949261687468386" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora podemos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;acessar&lt;/span&gt; os valores de um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_55"&gt;objeto&lt;/span&gt; dessa classe da seguinte forma:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SbRIOD2b7DI/AAAAAAAAAJQ/Xl3MtTqnRyc/s1600-h/code02.png"&gt;&lt;img style="cursor: pointer; width: 181px; height: 55px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SbRIOD2b7DI/AAAAAAAAAJQ/Xl3MtTqnRyc/s400/code02.png" alt="" id="BLOGGER_PHOTO_ID_5310949266965654578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Isso é possível graças há uma grande característica do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;Ruby&lt;/span&gt; chamada &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;Syntactic&lt;/span&gt; Sugar&lt;/span&gt;, que torna possível a criação de códigos mais amigáveis. No caso do exemplo acima o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_58"&gt;Ruby&lt;/span&gt; nos permite adicionar um espaço antes e depois do sinal de igual e não usar parênteses para invocar o método.&lt;br /&gt;&lt;br /&gt;Agora vamos falar sobre a parte interessante. Na verdade todo esse trabalho não precisa ser feito se eu for apenas criar métodos que permitam acesso ao conteúdo de uma variável.&lt;br /&gt;&lt;br /&gt;Existe um método chamado &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;accessor&lt;/span&gt; &lt;/span&gt;que faz todo esse trabalho para nós (cria a variável de instância e os métodos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_61"&gt;getters&lt;/span&gt; e &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_62"&gt;setters&lt;/span&gt; para ela).&lt;br /&gt;&lt;br /&gt;Para isso basta eu chamar o método e passar como parâmetros o nome dos campos que eu desejo que sejam minhas variáveis de instância. No caso de nosso exemplo, ficaria da seguinte forma:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SbRIOA3s3LI/AAAAAAAAAJY/nVl4Pkn1GJ4/s1600-h/class03.png"&gt;&lt;img style="cursor: pointer; width: 290px; height: 52px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SbRIOA3s3LI/AAAAAAAAAJY/nVl4Pkn1GJ4/s400/class03.png" alt="" id="BLOGGER_PHOTO_ID_5310949266165652658" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;E poderíamos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_63"&gt;acessar&lt;/span&gt; os dados da mesma forma que no outro exemplo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SbRIOD2b7DI/AAAAAAAAAJQ/Xl3MtTqnRyc/s1600-h/code02.png"&gt;&lt;img style="cursor: pointer; width: 181px; height: 55px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SbRIOD2b7DI/AAAAAAAAAJQ/Xl3MtTqnRyc/s400/code02.png" alt="" id="BLOGGER_PHOTO_ID_5310949266965654578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Como dito acima, o método &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_64"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_65"&gt;accessor&lt;/span&gt;&lt;/span&gt; cria métodos de acesso para leitura e escrita das variáveis de instância passadas a ele. Para os casos em que precisamos criar apenas os métodos de leitura ou escrita, usamos os métodos &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_66"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_67"&gt;reader&lt;/span&gt;&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_68"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_69"&gt;writer&lt;/span&gt;&lt;/span&gt;, em seu lugar.&lt;br /&gt;&lt;br /&gt;Bom pessoal, essa foi mais uma pequena contribuição no blog para o pessoal que deseja aprender mais sobre a linguagem &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_70"&gt;Ruby&lt;/span&gt;, a qual eu recomendo e encorajo o aprendizado.&lt;br /&gt;&lt;br /&gt;Para ler mais a respeito visitem a &lt;a href="http://www.ruby-doc.org/core/"&gt;API&lt;/a&gt; do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_71"&gt;ruby&lt;/span&gt; e procurem pelos métodos &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_72"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_73"&gt;accessor&lt;/span&gt;&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_74"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_75"&gt;reader&lt;/span&gt;&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_76"&gt;attr&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_77"&gt;writer&lt;/span&gt;&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_78"&gt;attr&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Gostaria de agradecer ao &lt;a href="http://www.fabiokung.com/"&gt;Fábio &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_79"&gt;Kung&lt;/span&gt;&lt;/a&gt; que me tirou dúvidas a respeito desse &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_80"&gt;post&lt;/span&gt; e está sempre me ajudando por e-mail.&lt;br /&gt;&lt;br /&gt;Espero que o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_81"&gt;post&lt;/span&gt; ajude, qualquer dúvida ou crítica podem mandar e-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_82"&gt;mails&lt;/span&gt; ou postar comentários.&lt;br /&gt;&lt;br /&gt;Até o próximo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_83"&gt;post&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Abraços!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-7235640276921220733?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/7235640276921220733/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=7235640276921220733' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7235640276921220733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7235640276921220733'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/03/ruby-getters-e-setters_08.html' title='Ruby: getters e setters'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/SbMCJnnKDdI/AAAAAAAAAIY/KoCSEAttubM/s72-c/a_errado.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-5108644168719867954</id><published>2009-03-07T19:20:00.009-03:00</published><updated>2009-03-08T20:55:50.646-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Como reinstalar o GRUB</title><content type='html'>Hoje passei por alguns apuros em meu &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;laptop&lt;/span&gt;&lt;/span&gt;, enquanto instalava o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Archlinux&lt;/span&gt;&lt;/span&gt; em uma nova partição do disco rígido.&lt;br /&gt;&lt;br /&gt;No meio da instalação via FTP, meu cabo de rede parou de funcionar e não voltou mais.&lt;br /&gt;&lt;br /&gt;Reiniciei o micro para &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;bootar&lt;/span&gt;&lt;/span&gt; pelo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Ubuntu&lt;/span&gt;&lt;/span&gt; (que era a distribuição que estava instalada antes) e descobri que o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;GRUB&lt;/span&gt;&lt;/span&gt; não carregava mais.&lt;br /&gt;&lt;br /&gt;Aparecia algo como:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Loading&lt;/span&gt;&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;GRUB&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Error&lt;/span&gt;&lt;/span&gt; 15&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Vim aqui passar adiante a solução que encontrei, para que ajude quem estiver com esse mesmo problema.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Para &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;re&lt;/span&gt;&lt;/span&gt;instalar o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;GRUB&lt;/span&gt;&lt;/span&gt; faça o seguinte:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Inicie o computador utilizando algum &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Live&lt;/span&gt;&lt;/span&gt; CD&lt;/span&gt; como o do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Ubuntu&lt;/span&gt;&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;por exemplo&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Inicie o console e digite:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;sudo&lt;/span&gt;&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;fdisk&lt;/span&gt;&lt;/span&gt; -l&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ele listará as partições de seus discos rígidos, localize qual é a partição onde está instalado o seu &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;linux&lt;/span&gt;&lt;/span&gt;. No meu caso é &lt;span style="font-weight: bold;"&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;dev&lt;/span&gt;&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;sda&lt;/span&gt;&lt;/span&gt;6&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Digite:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;sudo&lt;/span&gt;&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;grub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ele iniciará um aplicativo em modo texto, dentro dele digite:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;root&lt;/span&gt;&lt;/span&gt; (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;hd&lt;/span&gt;&lt;/span&gt;0,x)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Onde &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt; é o número da sua partição. Como a minha é &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;sda&lt;/span&gt;&lt;/span&gt;6&lt;/span&gt;, o número dela é &lt;span style="font-weight: bold;"&gt;5&lt;/span&gt;, pois a contagem começa do zero.&lt;br /&gt;&lt;br /&gt;Portanto, no meu caso o comando foi:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;root&lt;/span&gt; (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;hd&lt;/span&gt;0,5)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Então digite:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;setup&lt;/span&gt;&lt;/span&gt; (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;hd&lt;/span&gt;&lt;/span&gt;0)&lt;br /&gt;$ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;quit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Reinicie o micro e veja se está funcionando.&lt;br /&gt;&lt;br /&gt;Espero que o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;post&lt;/span&gt;&lt;/span&gt; ajude.&lt;br /&gt;Até o próximo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-5108644168719867954?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/5108644168719867954/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=5108644168719867954' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5108644168719867954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/5108644168719867954'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/03/como-re-instalar-o-grub.html' title='Como reinstalar o GRUB'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-154105283802180604</id><published>2009-03-01T13:34:00.003-03:00</published><updated>2009-03-01T13:38:25.185-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='evento'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Barcamp Locaweb de Ruby e Rails</title><content type='html'>Pessoal,&lt;br /&gt;&lt;br /&gt;Estou postando para ajudar a divulgar mais uma iniciativa muito interessante do pessoal da comunidade &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Ruby&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Mas detalhes no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;post&lt;/span&gt; do blog do Fábio &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Akita&lt;/span&gt;:&lt;br /&gt;&lt;a href="http://www.akitaonrails.com/2009/2/26/barcamp-locaweb-de-ruby-e-rails"&gt;&lt;br /&gt;http://www.akitaonrails.com/2009/2/26/barcamp-locaweb-de-ruby-e-rails&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Abraços!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-154105283802180604?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/154105283802180604/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=154105283802180604' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/154105283802180604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/154105283802180604'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/03/barcamp-locaweb-de-ruby-e-rails.html' title='Barcamp Locaweb de Ruby e Rails'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2692101204055585450</id><published>2009-02-22T23:27:00.009-03:00</published><updated>2009-02-24T01:03:01.168-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='servidores web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Como instalar o Mongrel</title><content type='html'>Uma dica rápida para quem, assim como eu, está começando em Ruby on Rails.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mongrel.rubyforge.org/"&gt;Mongrel&lt;/a&gt; é um rápido e simples servidor web para aplicações Rails, para instalá-lo e utilizá-lo em seus aplicativos, siga os passos a seguir:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Instalação:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo gem install mongrel&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Iniciando o servidor:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Acesse o diretório de sua aplicação, por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cd meuprojeto&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Inicialize o servidor:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ mongrel_rails start -d&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Para finalizá-lo utilize:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ mongrel_rails stop&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Se precisar reiniciá-lo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ mongrel_rails restart&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Mongrel é um servidor muito mais rápido que o WEBrick (o servidor que vem instalado por padrão junto ao Ruby on Rails) e é tão simples de usar quanto.&lt;br /&gt;&lt;br /&gt;Espero ter ajudado com a dica, abraços e até a próxima!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links relacionados:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://mongrel.rubyforge.org/"&gt;http://mongrel.rubyforge.org&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2692101204055585450?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2692101204055585450/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2692101204055585450' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2692101204055585450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2692101204055585450'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/02/como-instalar-o-mongrel.html' title='Como instalar o Mongrel'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8288451553446803669</id><published>2009-02-21T12:08:00.026-03:00</published><updated>2009-02-21T19:02:25.308-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Upload de imagens no Rails com Paperclip</title><content type='html'>Hoje vou escrever um tutorial sobre como fazer upload e redimensionamento de imagens no Ruby on Rails (RoR) utilizando o plug-in &lt;a href="http://thoughtbot.com/projects/paperclip"&gt;Paperclip&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O Paperclip é um plug-in muito simples de usar, estou utilizando ele em um projeto pessoal e é meu favorito para esse tipo de tarefa.&lt;br /&gt;&lt;br /&gt;Vou ensinar como usá-lo dando um exemplo prático. Vamos criar um projeto que tem uma classe &lt;span style="font-weight: bold;"&gt;user&lt;/span&gt; (usuário) com os campos &lt;span style="font-weight: bold;"&gt;name&lt;/span&gt; (nome) e &lt;span style="font-weight: bold;"&gt;picture&lt;/span&gt; (fotografia).&lt;br /&gt;&lt;br /&gt;Vamos criar uma tela de cadastro de usuários e uma tela que liste os usuários cadastrados, para podermos ver o Paperclip em ação.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criando o projeto.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para começar vamos criar nosso projeto, para isso vá para o seu diretório de projetos e digite o comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rails example --database=mysql&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;O nome do meu projeto é &lt;span style="font-weight: bold;"&gt;example&lt;/span&gt; e estou utilizando banco de dados &lt;span style="font-weight: bold;"&gt;mysql&lt;/span&gt;. Se você quiser utilizar outro nome ou banco de dados fique à vontade.&lt;br /&gt;&lt;br /&gt;Estou utilizando nome de variáveis em inglês pois recentemente comecei a seguir a recomendação que o &lt;a href="http://www.nomedojogo.com/"&gt;Carlos Brando&lt;/a&gt; fez no post &lt;a href="http://www.nomedojogo.com/2009/02/13/rails-way-3-nomes-de-metodos-e-variaveis-devem-ser-obvios/"&gt;Rails Way #3: Nomes de métodos e variáveis devem ser óbvios&lt;/a&gt;, recomendo a leitura.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Configurando o banco de dados.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora que o nosso projeto está criado vamos configurar o banco de dados, para isso abra o arquivo que está em &lt;span style="font-weight: bold;"&gt;config/database.yml&lt;/span&gt; com seu editor de textos.&lt;br /&gt;&lt;br /&gt;Escreva a senha de seu banco de dados nos respectivos lugares para os bancos  &lt;span style="font-weight: bold;"&gt;development&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;test&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;production&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Ficará similar à figura abaixo (a senha do meu banco de dados é root):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SaA4ZGHezyI/AAAAAAAAAHQ/50PJsFCFuwg/s1600-h/paperclip01.gif"&gt;&lt;img style="cursor: pointer; width: 331px; height: 137px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SaA4ZGHezyI/AAAAAAAAAHQ/50PJsFCFuwg/s400/paperclip01.gif" alt="" id="BLOGGER_PHOTO_ID_5305302364832321314" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Instalando o plug-in Paperclip.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos instalar o plugin do Paperclip em nosso projeto. Digite, no diretório do projeto, o comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ script/plugin install git://github.com/thoughtbot/paperclip.git&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ps. Você precisará ter o git instalado para executar esse comando, se você ainda não tem confira o post &lt;a href="http://brunograsselli.com.br/2009/02/instalar-git-no-ubuntu.html"&gt;Instalar GIT no Ubuntu&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criando o model &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;user&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos criar a classe &lt;span style="font-weight: bold;"&gt;user&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Como dito anterirmente, nossa classe terá os campos &lt;span style="font-weight: bold;"&gt;name&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;picture&lt;/span&gt;, que será o campo que amazenará a fotografia do usuário.&lt;br /&gt;&lt;br /&gt;Para que o paperclip funcione, ao invéz de criar os campo &lt;span style="font-weight: bold;"&gt;picture&lt;/span&gt; no model, criaremos os seguintes campos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;picture_file_name (string)&lt;/li&gt;&lt;li&gt;picture_content_type (string)&lt;/li&gt;&lt;li&gt;picture_file_size (integer)&lt;/li&gt;&lt;li&gt;picture_updated_at (datetime)&lt;/li&gt;&lt;/ul&gt;Onde &lt;span style="font-weight: bold;"&gt;picture&lt;/span&gt; é o nome que usaremos para se referir a imagem. Portanto se o nome que você escolheu fosse &lt;span style="font-weight: bold;"&gt;image&lt;/span&gt;, por exemplo, os nomes dos campos seriam &lt;span style="font-weight: bold;"&gt;image_updated_at&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;image_file_name&lt;/span&gt; e por aí vai.&lt;br /&gt;&lt;br /&gt;Digite o seguinte comando para criar o model &lt;span style="font-weight: bold;"&gt;user&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ script/generate model user name:string picture_file_name:string picture_content_type:string picture_file_size:integer picture_updated_at:datetime&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Configurando o campo &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;picture&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; na classe &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;user&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos dizer para a classe &lt;span style="font-weight: bold;"&gt;user&lt;/span&gt; que ela tem uma imagem que responde pelo nome de &lt;span style="font-weight: bold;"&gt;picture&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Para isso abra o arquivo que está em &lt;span style="font-weight: bold;"&gt;app/model/user.rb&lt;/span&gt; e adicione dentro da classe a linha:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;has_attached_file :picture, :styles =&gt; {:small =&gt; "150x150", :large =&gt; "550x550"}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Onde &lt;span style="font-weight: bold;"&gt;small&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;large&lt;/span&gt; são tamanhos que eu defini para que minha imagem tenha. Então quando eu fizer o upload de uma imagem o paperclip salvará, também, uma cópia dela nos tamanhos que eu especifiquei.&lt;br /&gt;&lt;br /&gt;Você pode definir mais tamanhos se quiser (ou menos) e os nomes ficam a seu critério.&lt;br /&gt;&lt;br /&gt;O arquivo ficará assim (clique na imagem para ampliar):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SaA_6NeW7hI/AAAAAAAAAHY/0q-nImzcWso/s1600-h/paperclip02.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 74px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SaA_6NeW7hI/AAAAAAAAAHY/0q-nImzcWso/s400/paperclip02.gif" alt="" id="BLOGGER_PHOTO_ID_5305310630324399634" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criando o banco de dados.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora para criar os bancos de dados e a tabela &lt;span style="font-weight: bold;"&gt;users &lt;/span&gt;vamos utilizar o &lt;span style="font-weight: bold;"&gt;rake&lt;/span&gt;.&lt;br /&gt;Digite os comandos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rake db:create:all&lt;br /&gt;$ rake db:migrate&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criando o controller para user.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos criar um controller para manipular o model &lt;span style="font-weight: bold;"&gt;user&lt;/span&gt;. Digite o comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;script/generate controller users&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Abra o arquivo gerado (&lt;span style="font-weight: bold;"&gt;app/controllers/users_controller.rb&lt;/span&gt;) e vamos criar as actions &lt;span style="font-weight: bold;"&gt;index&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;new&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;create&lt;/span&gt;. Por enquanto vamos deixá-las em branco, ficará assim:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SaBDA-nVCQI/AAAAAAAAAHg/cWIY0unLAag/s1600-h/paperclip03.gif"&gt;&lt;img style="cursor: pointer; width: 382px; height: 222px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SaBDA-nVCQI/AAAAAAAAAHg/cWIY0unLAag/s400/paperclip03.gif" alt="" id="BLOGGER_PHOTO_ID_5305314045129459970" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A action &lt;span style="font-weight: bold;"&gt;index&lt;/span&gt; listará os usuários cadastrados, a action &lt;span style="font-weight: bold;"&gt;new&lt;/span&gt; carregará o formulário de cadastro e a &lt;span style="font-weight: bold;"&gt;create&lt;/span&gt; criará o usuário digitado no formulário.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criando o formulário de cadastro.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Vamos criar a view para o formulário de cadastro, crie o arquivo &lt;span style="font-weight: bold;"&gt;app/views/new.html.erb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dentro dele crie o formulário de cadastro, veja o meu de exemplo (clique: na imagem para ampliá-la):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SaBFgfaBzBI/AAAAAAAAAHo/7ukYCRNEWs4/s1600-h/paperclip04.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 172px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SaBFgfaBzBI/AAAAAAAAAHo/7ukYCRNEWs4/s400/paperclip04.gif" alt="" id="BLOGGER_PHOTO_ID_5305316785531243538" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Lembrando que todo formulário que possui um campo &lt;span style="font-weight: bold;"&gt;file_field&lt;/span&gt; precisa ter o parâmetro &lt;span style="font-weight: bold;"&gt;:html =&gt; { :multipart =&gt; true }&lt;/span&gt; para funcionar. Senão o navegador não irá transferir o arquivo.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criando a action create.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos criar a action que cadastrará os dados do formulário, a action &lt;span style="font-weight: bold;"&gt;create&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Ela ficará assim (&lt;span style="font-weight: bold;"&gt;app/controllers/users_controller.rb&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SaBOARR3p_I/AAAAAAAAAIQ/epf5QkqwNbM/s1600-h/paperclip05.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 287px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SaBOARR3p_I/AAAAAAAAAIQ/epf5QkqwNbM/s400/paperclip05.gif" alt="" id="BLOGGER_PHOTO_ID_5305326127587764210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Essa action recebe os dados do formulário, cria um objeto do tipo &lt;span style="font-weight: bold;"&gt;user&lt;/span&gt; com esses dados e o salva no banco de dados. Se o procedimento deu certo ela vai para o index, que listará os usuários cadastrados, senão ela retorna para a página de cadastro.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criando a view para o index.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora que nosso projeto já cadastra usuários, vamos criar a view &lt;span style="font-weight: bold;"&gt;index&lt;/span&gt; para listá-los.&lt;br /&gt;&lt;br /&gt;Primeiramente faça com que a action &lt;span style="font-weight: bold;"&gt;index&lt;/span&gt; do controller &lt;span style="font-weight: bold;"&gt;users&lt;/span&gt; carregue uma variável com os usuários cadastrados, para isso (&lt;span style="font-weight: bold;"&gt;app/controllers/users_controller.rb&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SaBNcxbpDKI/AAAAAAAAAII/JrT7uQgJkYU/s1600-h/paperclip06.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 283px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SaBNcxbpDKI/AAAAAAAAAII/JrT7uQgJkYU/s400/paperclip06.gif" alt="" id="BLOGGER_PHOTO_ID_5305325517743393954" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora, para criar a view, crie o arquivo &lt;span style="font-weight: bold;"&gt;app/view/users/index.html.erb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Veja o meu de exemplo (clique na imagem para ampliá-la):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SaBM6pZvd2I/AAAAAAAAAIA/nvIz9IYu7k8/s1600-h/paperclip07.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 106px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SaBM6pZvd2I/AAAAAAAAAIA/nvIz9IYu7k8/s400/paperclip07.gif" alt="" id="BLOGGER_PHOTO_ID_5305324931472389986" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para exibir a imagem eu usei:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;%= image_tag u.picture.url(:small) %&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Onde &lt;span style="font-weight: bold;"&gt;u&lt;/span&gt; é o nome do objeto, &lt;span style="font-weight: bold;"&gt;picture&lt;/span&gt; é nosso campo de imagem, &lt;span style="font-weight: bold;"&gt;url&lt;/span&gt; retorna o endereço da imagem e &lt;span style="font-weight: bold;"&gt;:small&lt;/span&gt; é o tramanho que eu defini anteriormente.&lt;br /&gt;&lt;br /&gt;Para esse exemplo os seguintes códigos também funcionariam:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;%= image_tag u.picture.url() %&gt;&lt;br /&gt;&lt;%= image_tag u.picture.url(:small) %&gt;&lt;br /&gt;&lt;%= image_tag u.picture.url(:large) %&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Concluindo.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora já temos nosso sistema funcionando com upload e redimensionamento de imagens atravéz do plugin Paperclip.&lt;br /&gt;&lt;br /&gt;Digite:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ script/server&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;para iniciar o servidor e acesse: &lt;a href="http://localhost:3000/users"&gt;http://localhost:3000/users&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Resumindo.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Vou resumir o que se deve fazer para trabalhar com Paperclip:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Instalar o plug-in em seu projeto.&lt;/li&gt;&lt;li&gt;Criar os campos em sua model / tabela: sua_imagem_file_name (string), sua_imagem_content_type (string), sua_imagem_file_size (integer), sua_imagem_updated_at (datetime).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Definir, em seu model a propriedade has_attached_file com o nome do seu campo e estilos, se necessário.&lt;/li&gt;&lt;li&gt;Utilizar um formulário de cadastro com parâmetro multipart=&gt;true e o campo tipo file_field.&lt;/li&gt;&lt;li&gt;Para exibir, utilizar o método url do campo de imagem passando por parâmetro o tamanho da imagem que foi previamente definido.&lt;/li&gt;&lt;/ul&gt;Bom pessoal espero que tenham gostado do post, qualquer dúvida postem um comentário ou me mandem um e-mail (está escrito no meu perfil do blog).&lt;br /&gt;&lt;br /&gt;Abraços e até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8288451553446803669?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8288451553446803669/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8288451553446803669' title='6 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8288451553446803669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8288451553446803669'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/02/upload-de-imagens-no-rails-com.html' title='Upload de imagens no Rails com Paperclip'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/SaA4ZGHezyI/AAAAAAAAAHQ/50PJsFCFuwg/s72-c/paperclip01.gif' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4089368170160016536</id><published>2009-02-16T23:52:00.005-03:00</published><updated>2009-03-29T23:20:17.358-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Ruby Inside Brasil</title><content type='html'>Vou fazer um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;post&lt;/span&gt; rápido antes de dormir para ajudar a divulgar uma iniciativa muito interessante que acabo de ler no blog do &lt;a href="http://www.nomedojogo.com/2009/02/16/um-presente-para-a-comunidade-de-desenvolvedores-brasileiros-de-ruby-e-rails/"&gt;Carlos Brando (Nome do jogo)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Ele informa em seu &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;post&lt;/span&gt; o lançamento de um novo canal de comunicação para a comunidade &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Rails&lt;/span&gt; brasileira que trará informações sobre as novidades do mundo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Rails&lt;/span&gt;. Tanto as informações originais do &lt;a href="http://www.rubyinside.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Ruby&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Inside&lt;/span&gt;&lt;/a&gt; traduzidas para o português quanto artigos de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;desenvolvedores&lt;/span&gt; brasileiros sobre o tema.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Fiquem com o link, assinem o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;feed&lt;/span&gt; e bom proveito!&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.rubyinside.com.br/"&gt;&lt;img style="cursor: pointer; width: 145px; height: 36px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SdAsTIEpmDI/AAAAAAAAAKA/BFzACg-abQU/s400/logo-br.gif" alt="" id="BLOGGER_PHOTO_ID_5318799867020679218" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4089368170160016536?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4089368170160016536/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4089368170160016536' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4089368170160016536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4089368170160016536'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/02/ruby-inside-brasil.html' title='Ruby Inside Brasil'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_CGnpveaIy_M/SdAsTIEpmDI/AAAAAAAAAKA/BFzACg-abQU/s72-c/logo-br.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-1777568405833161450</id><published>2009-02-13T20:31:00.008-02:00</published><updated>2009-02-13T20:49:16.357-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='evento'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Ruby + Rails no mundo Real 2009</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SZX1SbfyE4I/AAAAAAAAAHA/vYquqcoNSyM/s1600-h/Rer2009.jpg"&gt;&lt;img style="cursor: pointer; width: 150px; height: 204px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SZX1SbfyE4I/AAAAAAAAAHA/vYquqcoNSyM/s400/Rer2009.jpg" alt="" id="BLOGGER_PHOTO_ID_5302413833266140034" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Dia 04 de abril acontecerá o &lt;span style="font-weight: bold;"&gt;Ruby + Rails no mundo Real 2009&lt;/span&gt; em São Paulo, será um evento bem interessante para os amantes do Rails.&lt;br /&gt;&lt;br /&gt;Direto do site &lt;a href="http://www.guru-sp.org/"&gt;Guru-SP&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;O primeiro grande evento das comunidades Guru-SP e Rails-BR apresentará algumas das mais importantes personalidades nacionais desse mercado com projetos e experiências reais.&lt;br /&gt;&lt;br /&gt;O seminário falará sobre temas do dia a dia, como controle de versão, testes, treinamentos, servidores de aplicação e mercado de trabalho (tanto interno como externo).&lt;br /&gt;&lt;br /&gt;Este evento também contará com a presença da equipe técnica da Sun Microsystems, apresentando como utilizar o servidor de aplicações GlassFish em aplicações Rails.&lt;br /&gt;&lt;br /&gt;É um evento imperdível pra quem trabalha com desenvolvimento de software e quer conhecer mais sobre a plataforma de software que está mudando rapidamente o mundo.&lt;br /&gt;&lt;br /&gt;Para saber mais detalhes sobre o evento visite a página do mesmo em &lt;a href="http://guru-sp.com/index.php/Ruby_e_Rails_no_mundo_real_-_primeira_edi%C3%A7%C3%A3o"&gt;Ruby e Rails no mundo real - primeira edição&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;Programação do evento:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;08:30 as 09:00: Credenciamento&lt;/li&gt;&lt;li&gt;09:00 as 09:15: Abertura do evento (Marcelo Castellani)&lt;/li&gt;&lt;li&gt;09:15 as 10:30: Criando um Instant Messenger usando Rails (Vinícius Baggio)&lt;/li&gt;&lt;li&gt;10:30 as 10:45: Ruby, Rails e empreendedorismo (Hugo Borges)&lt;/li&gt;&lt;li&gt;10:45 as 11:00: Coffee break&lt;/li&gt;&lt;li&gt;11:00 as 12:00: &lt;a href="http://www.fabiokung.com"&gt;Fabio Kung&lt;/a&gt; - a definir &lt;/li&gt;&lt;li&gt;12:00 as 13:00: Almoço&lt;/li&gt;&lt;li&gt;13:00 as 14:00: Outsorcing, ou como trabalhar para empresas gringas (Caffo)&lt;/li&gt;&lt;li&gt;14:00 as 15:00: GlassFish on Rails: Escalabilidade e Confiabilidade (Maurício Leal)&lt;/li&gt;&lt;li&gt;15:00 as 15:45: Testes em Ruby e Rails (Carlos Brando)&lt;/li&gt;&lt;li&gt;15:45 as 16:00: Coffee break&lt;/li&gt;&lt;li&gt;16:00 as 16:15: O que é e como funciona o RubyLearning (Willian Molinari)&lt;/li&gt;&lt;li&gt;16:15 as 17:15: Utilizando Gitorious nos seus projetos (&lt;a href="http://www.akitaonrails.com/"&gt;Fábio Akita&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;17:15 as 17:45: Desconferência&lt;/li&gt;&lt;li&gt;17:45 as 18:00: Encerramento&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;Faça sua inscrição no endereço &lt;a href="http://www.temporealeventos.com.br/?area=130"&gt;http://www.temporealeventos.com.br/?area=130&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;O local do evento será R. Teixeira da Silva, 647 - Paraíso - São Paulo - SP (Century Flat Paulista).&lt;br /&gt;&lt;br /&gt;Eu irei com certeza, já estou com a minha inscrição feita.&lt;br /&gt;&lt;br /&gt;Abraços, até o próximo post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-1777568405833161450?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/1777568405833161450/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=1777568405833161450' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1777568405833161450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1777568405833161450'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/02/ruby-rails-no-mundo-real-2009.html' title='Ruby + Rails no mundo Real 2009'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_CGnpveaIy_M/SZX1SbfyE4I/AAAAAAAAAHA/vYquqcoNSyM/s72-c/Rer2009.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-115188394112190021</id><published>2009-02-11T21:57:00.005-02:00</published><updated>2009-02-11T22:52:21.248-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Configurar teclado modelo americano para o alfabeto brasileiro no Ubuntu</title><content type='html'>Hoje vou fazer um post rápido para falar sobre algo que me ajudou muito essa semana.&lt;br /&gt;&lt;br /&gt;Comprei um laptop recentemente que possui o teclado com layout americano, suas teclas por padrão não trabalham com acentuação. Isso já estava me deixando louco quando ontem, no site do &lt;a href="http://www.vivaolinux.com.br/"&gt;Viva o Linux&lt;/a&gt;, eu li uma dica ensinando como fazer isso.&lt;br /&gt;&lt;br /&gt;A dica é do &lt;a href="http://www.vivaolinux.com.br/perfil/verPerfil.php?login=xibatapb"&gt;Eddie Hsu&lt;/a&gt; e o endereço original é &lt;a href="http://www.vivaolinux.com.br/dica/Configurando-teclado-com-layout-americano-para-funcionar-simbolos-do-alfabeto-brasileiro/"&gt;http://www.vivaolinux.com.br/dica/Configurando-teclado-com-layout-americano-para-funcionar-simbolos-do-alfabeto-brasileiro/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Resumindo ela, para configurar faça o seguinte:&lt;br /&gt;&lt;br /&gt;1) Vá em Sistema -&gt; Preferências -&gt; Teclado.&lt;br /&gt;&lt;br /&gt;2) &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Acesse&lt;/span&gt; a aba "&lt;span style="font-weight: bold;"&gt;Disposições&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;3) &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Selecione&lt;/span&gt; o modelo de seu teclado no item correspondente (o meu é &lt;span style="font-weight: bold;" class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Pc&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; (&lt;/span&gt;&lt;span style="font-weight: bold;" class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Intl&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;) Genérico de 105 teclas&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;4) Em "&lt;span style="font-weight: bold;"&gt;Disposições &lt;/span&gt;&lt;span style="font-weight: bold;" class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;selecionadas&lt;/span&gt;" &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;selecione&lt;/span&gt; "&lt;span style="font-weight: bold;"&gt;EUA Internacional (com teclas acentuáveis)&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;Pronto, está feito!&lt;br /&gt;&lt;br /&gt;Ps. Se você deseja configurar esse teclado no Windows, o nome dele lá é "&lt;span style="font-weight: bold;"&gt;English (United States) - United States - International&lt;/span&gt;"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-115188394112190021?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/115188394112190021/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=115188394112190021' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/115188394112190021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/115188394112190021'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/02/configurar-teclado-modelo-americano.html' title='Configurar teclado modelo americano para o alfabeto brasileiro no Ubuntu'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6685498352251062065</id><published>2009-02-08T17:16:00.006-02:00</published><updated>2009-02-08T18:44:44.290-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='editores de texto'/><title type='text'>Editores de texto para Ruby on Rails no Linux - gedit e Emacs</title><content type='html'>Hoje vou falar a respeito de dois editores de texto que, com algumas modificações, possibilitam um ambiente de desenvolvimento excelente em Rails no Linux, não sendo necessário o uso de IDEs como Netbeans ou Aptana RadRails. São eles o gedit e o Emacs.&lt;br /&gt;&lt;br /&gt;Ruby on Rails é um framework onde tudo pode ser feito atravéz de linha de comando, sendo assim eu defendo a ideia de que você não precisa de mais do que um bom editor de textos para desenvolver em Rails.&lt;br /&gt;&lt;br /&gt;Quando eu comecei a tentar fazer uns projetos com Rails eu estava utilizando o jEdit (editor que eu uso bastante para php), mas não estava totalmente satisfeito com a produtividade. Sempre ouvi falar do Textmate para Mac OS X, mas ainda não estou disposto a trocar de sistema operacional nem de computador.&lt;br /&gt;&lt;br /&gt;Vou ensinar a vocês como instalar os editores que eu mencionei e falar um pouco a respeito deles.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Primeira opção: gEdit + gmate&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;O gedit é o editor de textos padrão do Gnome, se você usa uma distribuição Linux com ambiente gráfico Gnome então você provavelmente já tem ele instalado.&lt;br /&gt;&lt;br /&gt;Vamos fazer algumas modificações nele para ele ficar mais adaptado ao Rails.&lt;br /&gt;&lt;br /&gt;Primeiramente vamos instalar o pacote de suporte a plugins, caso ainda não esteja instalado. Utilize o comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install gedit-plugins&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Outra coisa importante para se programar num editor é o recurso "recuo automático". Ele faz com que, quando você estiver usando tabulações ou espaços para indentar seu texto e for para a próxima linha, o editor adicione automaticamente a indentação.&lt;br /&gt;&lt;br /&gt;Para ativar essa opção abra o gedit e vá em:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Editar -&gt; Preferências -&gt; Editor&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;E marque a opção:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Habilitar recuo automático.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos instalar o gmate, que é um conjunto de plugins selecionados pelo &lt;a href="http://alexandredasilva.wordpress.com/gmate/"&gt;Alexandre da Silva&lt;/a&gt; para adaptar o gedit ao desenvolvimento de aplicações, principalmente em Rails. Para isso siga as etapas a seguir:&lt;br /&gt;&lt;br /&gt;1 - Se você está utilizando Ubuntu instale os seguintes programas no console do Linux:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install python-webkitgtk&lt;br /&gt;$ sudo apt-get install python-pyinotify&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;2 - Ainda no console do Linux vá para sua pasta pessoal (/home/seu_nome, geralmente o console já abre nessa pasta).&lt;br /&gt;&lt;br /&gt;3 - Digite o comando para clonar o arquivo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ git clone git://github.com/lexrupy/gmate.git&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ps. para isso você precisará ter o GIT instalado. Se você ainda não tem de uma olhada no post &lt;a href="http://brunograsselli.com.br/2009/02/instalar-git-no-ubuntu.html"&gt;http://brunograsselli.com.br/2009/02/instalar-git-no-ubuntu.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;4 - Entre na pasta que ele criou:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cd gmate&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;5 - Digite o comando para sua instalação:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sh install.sh&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Agora seu gedit já está com uma série de plug-ins instalados para o desenvolvimento Rails.&lt;br /&gt;&lt;br /&gt;Um que é muito útil é o &lt;span style="font-weight: bold;"&gt;Painel do navegador de arquivos&lt;/span&gt; (Editar -&gt; Preferências -&gt; Plug-ins).&lt;br /&gt;Ele exibe a árvore dos arquivos que estão em um determinado diretório (como o diretório do seu projeto, por exemplo).&lt;br /&gt;&lt;br /&gt;Para exibí-lo basta ativá-lo na parte de plug-ins:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Editar -&gt; Preferências -&gt; Plug-ins&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;e ativar sua exibição em:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ver -&gt; Painel lateral&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Com isso e os demais plug-ins você terá uma série de ferramentas a sua disposição.&lt;br /&gt;&lt;br /&gt;Agora vamos a nossa segunda opção:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Segunda opção: Emacs + emacs-rails&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O Emacs é um ótimo editor para Rails também. Ainda estou aprendendo como utilizá-lo mas ele já me surpreendeu com o pouco que eu vi.&lt;br /&gt;&lt;br /&gt;Para instalá-lo você pode efetuar o download em &lt;a href="http://www.gnu.org/software/emacs/"&gt;http://www.gnu.org/software/emacs/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Caso você esteja utilizando um distribuição originada do Debian (exemplo: Ubuntu) você não precisa fazer o download, pode instalar a partir do comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install emacs&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Após instalá-lo vamos instalar o conjunto de plug-ins &lt;span style="font-weight: bold;"&gt;emacs-rails&lt;/span&gt; criado po&lt;span style="font-family:Georgia,serif;"&gt;r &lt;a href="http://thiagopradi.net/"&gt;Thiago Pradi&lt;/a&gt;, &lt;a href="http://blog.ramonsoares.com/"&gt;Ramon Soares&lt;/a&gt; e &lt;a href="http://mgzmaster.wordpress.com/"&gt;Marcos Zimmermann&lt;/a&gt;,&lt;/span&gt; para isso siga as etapas:&lt;br /&gt;&lt;br /&gt;1 - Abra o console do Linux e vá para sua pasta pessoal (/home/seu_nome, geralmente o console já abre nessa pasta).&lt;br /&gt;&lt;br /&gt;2 - Digite o comando para clonar o arquivo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ git clone git://github.com/tchandy/emacs-rails.git&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;3 - Entre na pasta que ele criou:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cd emacs-rails&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;4 - Digite o comando para sua instalação:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cp -r .emacs* ~&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Pronto, agora você já tem o emacs adaptado para Ruby on Rails.&lt;br /&gt;&lt;br /&gt;Para abrir o mesmo painel de navegação de arquivos que eu comentei no gedit no Emacs basta ir em:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Options -&gt; Show/Hide -&gt; Speedbar&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Gostaria de agradecer ao &lt;span style="font-weight: bold;"&gt;nofxx&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;Fu&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;Patrick Spake&lt;/span&gt; da comunidade &lt;a href="http://rubyonbr.org/"&gt;Ruby on Br&lt;/a&gt;, foram eles que me deram as dicas dos editores e me ensinaram como instalá-los.&lt;br /&gt;&lt;br /&gt;Espero ter ajudado com o post, até o próximo!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links relacionados:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://projects.gnome.org/gedit/"&gt;http://projects.gnome.org/gedit&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://github.com/lexrupy/gmate/tree/master"&gt;http://github.com/lexrupy/gmate/tree/master&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gnu.org/software/emacs/"&gt;http://www.gnu.org/software/emacs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://github.com/tchandy/emacs-rails/tree/master"&gt;http://github.com/tchandy/emacs-rails/tree/master&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6685498352251062065?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6685498352251062065/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6685498352251062065' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6685498352251062065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6685498352251062065'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/02/editores-de-texto-para-ruby-on-rails-no.html' title='Editores de texto para Ruby on Rails no Linux - gedit e Emacs'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-1174537496485830560</id><published>2009-02-04T21:11:00.012-02:00</published><updated>2009-02-05T19:48:41.772-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>How to Install GIT on Ubuntu (in English)</title><content type='html'>From today I'll start to post some topics translated to English, to help more users.&lt;br /&gt;&lt;br /&gt;Forgive my English, it isn't perfect but I hope it will do.&lt;br /&gt;&lt;br /&gt;Today I'll make a quick post about how to install &lt;span style="font-weight: bold;"&gt;GIT&lt;/span&gt; on &lt;span style="font-weight: bold;"&gt;Ubuntu&lt;/span&gt;.&lt;br /&gt;GIT is a software to handle and delivery versions of projects, it was made by Linus Torvalds for the Kernel's project and, nowadays, it is used for many other projects, such as &lt;span style="font-weight: bold;"&gt;Ruby on Rails&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;When I posted about how to install Rails on Ubuntu I didn't mention GIT, but you'll realize that is very useful to have it installed because there are many plugins for Rails stored on GIT repositories.&lt;br /&gt;&lt;br /&gt;To install it is very simple, you only have to use this command:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install git-core git-doc git-svn git-gui gitk&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In your journey in Ruby on Rails' world you will find many plugins that needs GIT for their installation, but it won't be a problem anymore.&lt;br /&gt;&lt;br /&gt;See you!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Related links:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://git-scm.com/"&gt;http://git-scm.com&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Other languages:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://brunograsselli.com.br/2009/02/instalar-git-no-ubuntu.html"&gt;Versão em Português&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-1174537496485830560?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/1174537496485830560/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=1174537496485830560' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1174537496485830560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/1174537496485830560'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/02/how-to-install-git-on-ubuntu-in-english.html' title='How to Install GIT on Ubuntu (in English)'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6097634160343379165</id><published>2009-02-04T20:07:00.010-02:00</published><updated>2009-02-05T22:04:24.867-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Instalar GIT no Ubuntu</title><content type='html'>Hoje vou fazer um post rápido para ensinar como instalar o &lt;span style="font-weight: bold;"&gt;GIT&lt;/span&gt; no &lt;span style="font-weight: bold;"&gt;Ubuntu&lt;/span&gt;.&lt;br /&gt;O GIT é um software para gerenciamento de versões de projetos, foi criado pelo Linus Torvalds para o projeto do Kernel do Linux e, hoje em dia, é utilizado por uma série de outros projetos, entre eles o &lt;span style="font-weight: bold;"&gt;Ruby on Rails&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Quando eu bloguei há uns dias atrás sobre a instalação do Rails no Ubuntu eu não comentei sobre o GIT, mas você vai perceber que é muito útil ter ele instalado pois existem muitos plugins para Rails que estão armazenados em repositórios GIT.&lt;br /&gt;&lt;br /&gt;Para instalá-lo é bem simples, basta utilizar o comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install git-core git-doc git-svn git-gui gitk&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ao longo de sua jornada pelo mundo Ruby on Rails você irá se deparar com vários plugins que necessitam do GIT para sua instalação, mas agora isso não é mais um problema.&lt;br /&gt;&lt;br /&gt;Até o próximo post!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links relacionados:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://git-scm.com/"&gt;http://git-scm.com&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Outros idiomas:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://brunograsselli.com.br/2009/02/how-to-install-git-on-ubuntu-in-english.html"&gt;English version&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6097634160343379165?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6097634160343379165/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6097634160343379165' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6097634160343379165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6097634160343379165'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/02/instalar-git-no-ubuntu.html' title='Instalar GIT no Ubuntu'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2229249280564687462</id><published>2009-02-01T13:21:00.005-02:00</published><updated>2009-02-01T13:36:39.400-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Configurar banda larga 3G no Ubuntu 8.10</title><content type='html'>Recentemente comecei a utilizar o serviço de banda larga da Claro 3G no meu laptop. Me surpreendi com a facilidade de configuração desse tipo de conexão no Ubuntu 8.10 Intrepid Ibex (digo isso pois tinha pesquisado a respeito da instalação em outras versões do Ubuntu e parecia um pouco trabalhoso).&lt;br /&gt;&lt;br /&gt;Para configurar inicie o Ubuntu com o modem conectado à porta USB. Para verificar se o Ubuntu detectou o modem você pode utilizar o comando:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;$ lsusb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Após iniciar o sistema clique sobre o ícone de conexão de rede que fica próximo ao relógio e selecione o item "configurar".&lt;br /&gt;&lt;br /&gt;Abrirá uma janela e, após clicar em "Frente", te dará opções de país e operadora, basta selecionar a operadora desejada.&lt;br /&gt;&lt;br /&gt;De um nome à sua conexão e conclua o processo.&lt;br /&gt;&lt;br /&gt;Após isso a internet já deve estar funcionando! Para conectar basta clicar no item de conexão de rede novamente e selecionar o item da conexão que acaba de ser configurada.&lt;br /&gt;&lt;br /&gt;Em alguns casos ocorre de ele estar conectado mas mesmo assim o Firefox não exibir as páginas. Isso aconteceu no meu caso. Para solucionar utilize o comando abaixo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;$ sudo gedit /etc/ppp/options&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Esse comando abrirá um arquivo texto pelo gedit. No final desse arquivo adicione a linha:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ipcp-max-failure 30&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Salve o arquivo e reinicie o micro, agora deve funcionar (no meu micro funcionou dessa forma, eu utilizo um modem Huawei E226).&lt;br /&gt;&lt;br /&gt;Até a próxima pessoal!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2229249280564687462?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2229249280564687462/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2229249280564687462' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2229249280564687462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2229249280564687462'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/02/configurar-banda-larga-3g-no-ubuntu-810.html' title='Configurar banda larga 3G no Ubuntu 8.10'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-3792152945140434363</id><published>2009-01-27T21:14:00.006-02:00</published><updated>2009-01-27T23:25:48.049-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Configurando regras de acentuação manualmente no Ruby on Rails</title><content type='html'>&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;O Ruby on Rails é um dos frameworks que mais aplica o paradigma &lt;span style="font-style: italic; font-weight: bold;"&gt;Convention over Configuration&lt;/span&gt; em sua estrutura.&lt;br /&gt;&lt;br /&gt;O intuito desse paradigma é fazer com que o programador só precise configurar (especificar) os aspectos da sua aplicação que não seguem a convenção da linguagem. Sendo assim se ele sempre seguir a convenção ele não precisa efetuar nenhuma configuração adicional.&lt;br /&gt;&lt;br /&gt;Por exemplo, o Rails possui uma convenção de que classes devem possuir nomes no singular e, as respectivas tabelas no banco de dados, devem possuir o mesmo nome no plural. Se você criar uma classe House, o Ruby on Rails vai entender que a tabela correspondente para salvar os registros da classe&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;House no banco de dados é a tabela Houses, no plural.&lt;br /&gt;&lt;br /&gt;Caso você deseje utilizar uma tabela com outro nome para esse propósito, você terá que configurá-la manualmente. Mas caso você aceite a convenção do Rails e utilize o nome da tabela como Houses, então você não precisará configurar nada, apenas digite house&lt;span style="font-weight: bold;"&gt;.&lt;/span&gt;save&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;e o Rails irá salvar o registro na tabela correspondente (bem mais prático).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;O porque de toda essa explicação.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para saber qual o nome da tabela correspondente no banco de dados, o Rails faz uso do método &lt;span style="font-weight: bold;"&gt;pluralize&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Esse método recebe uma string como argumento e retorna uma outra string com o plural da palavra recebida.&lt;br /&gt;&lt;br /&gt;Faça um teste, abra o diretório do seu projeto pelo console do Linux / Mac e digite:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;script/console&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Isso abrirá um console parecido com o IRB, mas com todo o ambiente do Rails carregado junto a ele.&lt;br /&gt;&lt;br /&gt;Nesse console digite, por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"house".pluralize&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"child".pluralize&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"person".pluralize&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Os resultados serão&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"houses"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"children"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"people"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Viram, o Rails sabe trabalhar até com plurais irregulares do inglês.&lt;br /&gt;Mas, como eu disse, o Rails só sabe trabalhar com inglês. Por exemplo, se você digitar &lt;span style="font-weight: bold;"&gt;"imagem".pluralize&lt;/span&gt; o resultado será &lt;span style="font-weight: bold;"&gt;"imagems"&lt;/span&gt; e não &lt;span style="font-weight: bold;"&gt;"imagens"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Meu objetivo nesse post é ensinar uma forma rápida de se configurar regras de pluralização em outras línguas no Rails.&lt;br /&gt;&lt;br /&gt;É lógico que hoje em dia existem plugins / gems para o Rails que contém todas as regras de pluralização em português (&lt;a href="http://www.improveit.com.br/software_livre/brazilian_rails"&gt;Brazilian Rails&lt;/a&gt;), mas vamos dizer que você só precise de uma ou duas para um projeto ou um teste que você está fazendo. Vou explicar como fazer.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Configurando regras de pluralização.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O processo é bem simples, abra com um editor de texto ou IDE o arquivo que está dentro da pasta do seu projeto em:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;./config/initializers/inflections.rb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Descomente as linhas:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ActiveSupport::Inflector.inflections do |inflect|&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;e&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(Se elas não estiverem comentadas simplesmente digite-as).&lt;br /&gt;&lt;br /&gt;Dentro deste bloco digite as regras que deseja. Dentro do arquivo inflections.rb existem alguns exemplos de regras (comentados). Segue uma de exemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;inflect.irregular 'imagem', 'imagens'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Seu arquivo deve ficar assim:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ActiveSupport::Inflector.inflections do |inflect|&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    inflect.irregular 'imagem', 'imagens'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Basta salvar e reiniciar o console (ou o servidor, depende de onde você estiver testando) e já estará funcionando.&lt;br /&gt;&lt;br /&gt;Pessoal, espero ter ajudado, qualquer dúvida sintam-se livres para perguntar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-3792152945140434363?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/3792152945140434363/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=3792152945140434363' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3792152945140434363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/3792152945140434363'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/01/configurando-regras-de-acentuacao.html' title='Configurando regras de acentuação manualmente no Ruby on Rails'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-635777627157394564</id><published>2009-01-24T12:26:00.006-02:00</published><updated>2009-01-24T17:33:54.046-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='livros'/><title type='text'>Dica de livro: Getting Real</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SXsmbFgviYI/AAAAAAAAAG4/UmMrsF0n0rg/s1600-h/gettingreal.jpg"&gt;&lt;img style="cursor: pointer; width: 263px; height: 400px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SXsmbFgviYI/AAAAAAAAAG4/UmMrsF0n0rg/s400/gettingreal.jpg" alt="" id="BLOGGER_PHOTO_ID_5294868033681983874" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Recentemente fiz um curso sobre Ruby on Rails, onde me indicaram a leitura do livro "Getting Real" da 37signals.&lt;br /&gt;&lt;br /&gt;Estou aqui para recomendá-lo a todos vocês pois o livro é realmente muito bom e agrega muito valor ao leitor, seja ele um programador, analista, designer ou até de uma área não relacionada a informática.&lt;br /&gt;&lt;br /&gt;Ele fala a respeito de projetos, formação de equipes, entre outros. Sempre trazendo exemplos de casos similares bem sucedidos na área.&lt;br /&gt;&lt;br /&gt;O livro é pequeno, possui versão em português gratuita no próprio site da 37signals, vale a pena dar uma olhada.&lt;br /&gt;&lt;br /&gt;Para quem não sabe a 37signals é a empresa por trás da criação do Ruby on Rails, entre outros projetos. A empresa tem uma visão bem peculiar a respeito de projetos (opinionated), defende idéias como "Faça menos que a concorrência", ou "Comece com não".&lt;br /&gt;&lt;br /&gt;Seguem links abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gettingreal.37signals.com/GR_por.php"&gt;Getting Real - Versão Online em Português&lt;/a&gt;&lt;br /&gt;&lt;a href="http://gettingreal.37signals.com/toc.php"&gt;Getting Real - Original Version&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-635777627157394564?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/635777627157394564/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=635777627157394564' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/635777627157394564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/635777627157394564'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/01/dica-de-livro-getting-real.html' title='Dica de livro: Getting Real'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/SXsmbFgviYI/AAAAAAAAAG4/UmMrsF0n0rg/s72-c/gettingreal.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8233360141704518123</id><published>2009-01-18T20:37:00.022-02:00</published><updated>2010-04-30T10:10:45.127-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Instalar Ruby on Rails + MySQL no Ubuntu</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Post Atualizado em 30/04/2010, todos os dados estão atualizados.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hoje estou voltando a postar no blog e, para iniciar o ano, vou começar a falar sobre uma linguagem diferente das comentadas aqui anteriormente, a linguagem Ruby junto com o framework Rails.&lt;br /&gt;&lt;br /&gt;Este post ensinará como instalar o Ruby on Rails no Ubuntu, vamos lá!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Instalado o Ruby.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para instalar o ruby utilizaremos os comandos abaixo, que devem ser digitados no console do Linux.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo apt-get install build-essential&lt;br /&gt;sudo apt-get install ruby1.8 ruby1.8-dev rdoc1.8 ri1.8 irb1.8&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Instalando o RubyGems.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O gems é um gerenciador de pacotes, que te ajudará a instalar facilmente diversas aplicações referentes a ruby, similar ao apt-get do debian.&lt;br /&gt;&lt;br /&gt;Vamos utilizá-lo para instalar os próximos pacotes.&lt;br /&gt;&lt;br /&gt;Para instalá-lo, digite o comandos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz&lt;br /&gt;tar xvzf rubygems-1.3.5.tgz&lt;br /&gt;cd rubygems-1.3.5/&lt;br /&gt;sudo ruby1.8 setup.rb&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Isso instalará a versão 1.3.5 do gems. Caso você deseje verificar se existe uma mais recente, você pode acessar o endereço:&lt;br /&gt;&lt;br /&gt;&lt;a style="font-weight: bold;" href="http://rubyforge.org/frs/?group_id=126"&gt;http://rubyforge.org/frs/?group_id=126&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Configurando links para o Ubuntu.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O apt-get do Ubuntu mantém os nomes dos pacotes que instalamos como: ruby1.8, gem1.8, rdoc1.8, ri1.8, irb1.8.&lt;br /&gt;&lt;br /&gt;Esses nomes não são muito bons para se trabalhar, então vamos criar alguns links mais amigáveis. Utilize os comandos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo ln -s /usr/bin/gem1.8 /usr/bin/gem&lt;br /&gt;sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby&lt;br /&gt;sudo ln -s /usr/bin/rdoc1.8 /usr/bin/rdoc&lt;br /&gt;sudo ln -s /usr/bin/ri1.8 /usr/bin/ri&lt;br /&gt;sudo ln -s /usr/bin/irb1.8 /usr/bin/irb&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Atualizando o Gems.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Digite o comando abaixo para verificar se existe alguma atualização disponível para o rubygems:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo gem update --system&lt;br /&gt;sudo gem sources -a http://gems.github.com&lt;br /&gt;sudo gem sources -a http://gemcutter.org&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Após instalar o gems execute o comando abaixo para verificar se existe alguma atualização disponível para ele:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Instalando o Rails.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Vamos utilizar o gems para instalar o Rails, para isso digite os comandos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo gem install rails&lt;br /&gt;sudo apt-get install libopenssl-ruby&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Instalando o MySQL.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Utilizarei o MySQL como banco de dados em minhas aplicações Rails, seguem os comandos para instalá-lo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo apt-get install mysql-server-5.1&lt;br /&gt;sudo apt-get install libmysqlclient15-dev&lt;br /&gt;sudo gem install mysql&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Concluindo.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Com isso você já terá Ruby on Rails funcionando no seu Ubuntu.&lt;br /&gt;Eu testei os comandos em diversas versões do Ubuntu e micros diferentes, dentre as versões estão: Ubuntu 8.10 (Intrepid Ibex), Ubuntu 9.04 (Jaunty Jackalope), Ubuntu 9.10 (Karmic Koala) e Ubuntu 10.04 (Lucid Lynx), mas acredito que em outras versões também funcione perfeitamente.&lt;br /&gt;Se você testou em alguma outra versão por favor me informe, será de grande ajuda.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;IDEs.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Muita gente defende que Ruby on Rails não precisa de IDE, e eu não sou totalmente contra esse idéia, mas se você deseja instalar alguma você tem várias opções, como por exemplo o &lt;a href="http://www.netbeans.org/downloads/"&gt;NetBeans&lt;/a&gt; e o &lt;a href="http://www.aptana.com/studio/download"&gt;Aptana  RadRails&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A instalação do NetBeans é um pouco mais fácil que a do Aptana (basta executar o instalador).&lt;br /&gt;&lt;br /&gt;Se você optar pelo Aptana você deve baixar o Aptana Studio e depois instalar o plugin para manipulação de projeto Rails, para isso:&lt;br /&gt;&lt;br /&gt;Menu Help -&gt; Software Updates -&gt; Find and Install -&gt; Search for new features to install (selecione Aptana RadRails Development Environment.&lt;br /&gt;&lt;br /&gt;Espero que o post ajude, qualquer dúvida entre em contato.&lt;br /&gt;&lt;br /&gt;Visite também o post sobre a instalação do GIT no Ubuntu:&lt;br /&gt;&lt;a href="http://brunograsselli.com.br/2009/02/instalar-git-no-ubuntu.html"&gt;http://brunograsselli.com.br/2009/02/instalar-git-no-ubuntu.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Os posts sobre editores de texto para Ruby on Rails:&lt;br /&gt;&lt;a href="http://brunograsselli.com.br/2009/02/editores-de-texto-para-ruby-on-rails-no.html"&gt;http://brunograsselli.com.br/2009/02/editores-de-texto-para-ruby-on-rails-no.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;E:&lt;br /&gt;&lt;a href="http://brunograsselli.com.br/2009/04/vim-ruby-on-rails.html"&gt;http://brunograsselli.com.br/2009/04/vim-ruby-on-rails.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links relacionados:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ruby-lang.org/"&gt;http://www.ruby-lang.org&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://rubyonrails.org/"&gt;http://www.rubyonrails.org&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.netbeans.org/downloads/"&gt;http://www.netbeans.org/downloads&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.aptana.com/studio/download"&gt;http://www.aptana.com/studio/download&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Post Atualizado em 30/04/2010, todos os dados estão atualizados.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8233360141704518123?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8233360141704518123/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8233360141704518123' title='8 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8233360141704518123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8233360141704518123'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2009/01/instalar-ruby-on-rails-mysql-no-ubuntu.html' title='Instalar Ruby on Rails + MySQL no Ubuntu'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4520703417500771380</id><published>2008-12-19T01:11:00.002-02:00</published><updated>2008-12-19T01:19:56.606-02:00</updated><title type='text'>Multi-touch Whiteboard de baixo custo utilizando um Wiimote</title><content type='html'>Saudações pessoal,&lt;br /&gt;&lt;br /&gt;Esses últimos dias não estou conseguindo postar no blog pois estou no meio de um intercâmbio em Toronto, Canadá. Retornarei dia 28 de dezembro e acredito que conseguirei retornar aos tópicos sobre programação e desenvolvimento.&lt;br /&gt;&lt;br /&gt;Estou passando para mostrar um vídeo que assisti há algum tempo atrás que é muito interessante. O vídeo mostra como interagir com uma imagem projetada na parede utilizando uma caneta e um joystick de Nintendo Wii.&lt;br /&gt;&lt;br /&gt;Até breve, segue vídeo abaixo.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/5s5EvhHy7eQ&amp;amp;hl=pt-br&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/5s5EvhHy7eQ&amp;amp;hl=pt-br&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4520703417500771380?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4520703417500771380/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4520703417500771380' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4520703417500771380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4520703417500771380'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/12/multi-touch-whiteboard-de-baixo-custo.html' title='Multi-touch Whiteboard de baixo custo utilizando um Wiimote'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8740720722700200609</id><published>2008-11-25T23:04:00.009-02:00</published><updated>2008-11-25T23:31:32.334-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='jedit'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='editores de texto'/><title type='text'>jEdit com a fonte embaçada / desfocada no Ubuntu</title><content type='html'>Saudações pessoal,&lt;br /&gt;&lt;br /&gt;O post que eu vou fazer hoje é sobre um problema bem específico que tive com o &lt;a href="http://www.jedit.org/"&gt;jEdit&lt;/a&gt; (ótimo editor de texto para linguagens de programação) recentemente, mas pode ser útil para quem esteja passando pela mesma situação.&lt;br /&gt;&lt;br /&gt;Tive que reinstalar o Ubuntu na minha máquina e, quando instalei o jEdit, ele estava com a fonte fora de foco, impraticável para o uso. Estava como na imagem abaixo (clique para ampliá-la):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SSyiXq_ZSWI/AAAAAAAAAGo/mXXeARH75dY/s1600-h/Captura_da_tela-jEdit+-+controleestoque.class.php.png"&gt;&lt;img style="cursor: pointer; width: 373px; height: 400px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SSyiXq_ZSWI/AAAAAAAAAGo/mXXeARH75dY/s400/Captura_da_tela-jEdit+-+controleestoque.class.php.png" alt="" id="BLOGGER_PHOTO_ID_5272767791304886626" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Da pra perceber bem pelos sinais de igual, e a própria interface do aplicativo está estranha.&lt;br /&gt;&lt;br /&gt;Pesquisei na internet e encontrei uma solução no site oficial do jEdit.&lt;br /&gt;&lt;br /&gt;O que estava acontecendo é que, apesar de eu ter instalado o jre 6 do java, o runtime que estava como padrão no meu Linux era o openjdk 6.&lt;br /&gt;&lt;br /&gt;Se você estiver com esse mesmo problema, basta alterar o runtime padrão do java para uma compatível ao jEdit, para fazer isso basta utilizar o comando:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;$ sudo update-alternatives --config java&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;E selecionar a runtime desejada digitando o número correspondente.&lt;br /&gt;&lt;br /&gt;Se você ainda não tiver instalado nenhuma runtime do java compatível, você pode instalar a partir do comando (o jre 1.5 também é compatível):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;$ sudo apt-get install sun-java6-jre&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Com isso o problema deve resolver, e o jEdit ficará normal, como mostra a figura:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SSykMjDuZDI/AAAAAAAAAGw/w1LRwxUK8bQ/s1600-h/Captura_da_tela-jEdit+-+controleestoque.class.php-1.png"&gt;&lt;img style="cursor: pointer; width: 370px; height: 400px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SSykMjDuZDI/AAAAAAAAAGw/w1LRwxUK8bQ/s400/Captura_da_tela-jEdit+-+controleestoque.class.php-1.png" alt="" id="BLOGGER_PHOTO_ID_5272769799220257842" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Até a próxima, espero ter ajudado!&lt;br /&gt;&lt;br /&gt;Ps. se você ainda não usa o jEdit e ficou curioso, pode instalá-lo a partir do comando:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;$ sudo apt-get install jedit&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; relacionados:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.jedit.org/"&gt;http://www.jedit.org&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8740720722700200609?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8740720722700200609/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8740720722700200609' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8740720722700200609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8740720722700200609'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/11/jedit-com-fonte-embaada-desfocada-no.html' title='jEdit com a fonte embaçada / desfocada no Ubuntu'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/SSyiXq_ZSWI/AAAAAAAAAGo/mXXeARH75dY/s72-c/Captura_da_tela-jEdit+-+controleestoque.class.php.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2946024586193720618</id><published>2008-11-19T15:10:00.014-02:00</published><updated>2008-11-19T16:35:52.923-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='video aula'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Layout CSS, Aula 3 - Alinhando um DIV a esquerda do outro</title><content type='html'>Bom pessoal,&lt;br /&gt;&lt;br /&gt;Depois de algum tempo, consegui gravar o último vídeo do nosso assunto sobre Layout CSS.&lt;br /&gt;Neste post nós veremos como criar as DIV's internas. Veremos como alinhar uma DIV ao lado da outra e, também um truque muito usado em CSS chamado faux columns.&lt;br /&gt;&lt;br /&gt;Bom, como de costume, vou deixar aqui no início o vídeo, para ajudar no aprendizado:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/9TIGHvVwx18&amp;amp;hl=pt-br&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/9TIGHvVwx18&amp;amp;hl=pt-br&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Bom, abaixo segue o código de onde nós paramos no último post (no primeiro post nós criamos a DIV principal e a alinhamos a esquerda e, no segundo, fizemos ela ocupar 100% da altura da tela):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SSRKgL_7mWI/AAAAAAAAAFQ/R960i6_R2BE/s1600-h/P03-F01.gif"&gt;&lt;img style="cursor: pointer; width: 328px; height: 400px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SSRKgL_7mWI/AAAAAAAAAFQ/R960i6_R2BE/s400/P03-F01.gif" alt="" id="BLOGGER_PHOTO_ID_5270419380767529314" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Lembrando que basta clicar na figura para ampliá-la.&lt;br /&gt;&lt;br /&gt;O que falta para chegarmos até o formato do site esperado são as 3 DIV's internas. Vou colocar novamente a imagem com o formato que desejamos montar:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SSRPPEISgSI/AAAAAAAAAFY/gxTy2SIe-OA/s1600-h/layout.gif"&gt;&lt;img style="cursor: pointer; width: 322px; height: 242px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SSRPPEISgSI/AAAAAAAAAFY/gxTy2SIe-OA/s400/layout.gif" alt="" id="BLOGGER_PHOTO_ID_5270424584155463970" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criando as DIV's Internas&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora sim vamos continuar da onde paramos.&lt;br /&gt;Primeiramente vamos criar três DIV's dentro da DIV principal. Seus id's serão "topo", "menu" e "rodapé".&lt;br /&gt;Conforme figura abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SSRQHqSO4jI/AAAAAAAAAFg/v0yHFgZW9A0/s1600-h/P03-F02.gif"&gt;&lt;img style="cursor: pointer; width: 306px; height: 400px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SSRQHqSO4jI/AAAAAAAAAFg/v0yHFgZW9A0/s400/P03-F02.gif" alt="" id="BLOGGER_PHOTO_ID_5270425556470391346" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ps. Como o código já está grande, não posso mais colocá-lo inteiro dentro das figuras. Por isso estou numerando as linhas, para você saber que esse não é o código completo.&lt;br /&gt;&lt;br /&gt;Agora irei definir uma altura para a DIV "topo" e uma borda (apenas na parte de baixo).&lt;br /&gt;Para fazer isso adicionarei um novo bloco no CSS com o seletor #topo, conforme figura abaixo.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SSRQmDYvxNI/AAAAAAAAAFo/ofEyIpVraok/s1600-h/P03-F03.gif"&gt;&lt;img style="cursor: pointer; width: 316px; height: 400px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SSRQmDYvxNI/AAAAAAAAAFo/ofEyIpVraok/s400/P03-F03.gif" alt="" id="BLOGGER_PHOTO_ID_5270426078604674258" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos começar a criar o CSS para as DIV's "menu" e "conteudo".&lt;br /&gt;Primeiramente, vou definir uma largura fixa para as duas (130 px) e uma cor de fundo para cada uma (#faa para o menu e #aaf para o conteúdo).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SSRRakSpVJI/AAAAAAAAAFw/QNSgc221Vjw/s1600-h/P03-F04.gif"&gt;&lt;img style="cursor: pointer; width: 319px; height: 400px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SSRRakSpVJI/AAAAAAAAAFw/QNSgc221Vjw/s400/P03-F04.gif" alt="" id="BLOGGER_PHOTO_ID_5270426980790654098" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Como você pode ver as DIV's ficaram uma em cima da outra. Para corrigir isso vamos utilizar a propriedade "float", que fará com que cada uma delas flutue em relação a DIV principal. Vamos definir float: left para o menu e right para o conteúdo.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SSRTHPXw5aI/AAAAAAAAAF4/5-V8Avg3xQk/s1600-h/P03-F05.gif"&gt;&lt;img style="cursor: pointer; width: 323px; height: 400px;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SSRTHPXw5aI/AAAAAAAAAF4/5-V8Avg3xQk/s400/P03-F05.gif" alt="" id="BLOGGER_PHOTO_ID_5270428847780717986" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora cada DIV já está posicionada no seu respectivo lugar.&lt;br /&gt;Vamos então definir uma largura para o menu e o conteúdo, para que cada um ocupe todo o espaço disponível para eles.&lt;br /&gt;&lt;br /&gt;Como a DIV principal tem 600px, vou utilizar 130px para o menu e 469px para o conteúdo. Fazendo isso deixarei entre eles um espaço de 1 px, que eu utilizarei mais para frente.&lt;br /&gt;Segue figura:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SSRUIT8FGvI/AAAAAAAAAGA/Kx3gUvPMFDw/s1600-h/P03-F06.gif"&gt;&lt;img style="cursor: pointer; width: 310px; height: 400px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SSRUIT8FGvI/AAAAAAAAAGA/Kx3gUvPMFDw/s400/P03-F06.gif" alt="" id="BLOGGER_PHOTO_ID_5270429965698276082" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora vamos definir uma borda entre o menu e o conteúdo.&lt;br /&gt;Para fazer isso, a técnica escolhida será o faux columns. Criarei uma imagem com a largura da DIV principal (600px) e apenas 1px de altura.&lt;br /&gt;Farei com que essa imagem tenha fundo transparente e pintarei nela apenas 1 pixel preto, justamente na posição onde está sobrando um pixel vazio em nosso layout. Definirei essa imagem como fundo da DIV principal.&lt;br /&gt;Sendo assim ela se repetirá e pintará uma borda entre as duas DIV's (menu e conteúdo).&lt;br /&gt;&lt;br /&gt;Segue abaixo o código onde insiro a imagem como fundo da DIV principal:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SSRVbno9i4I/AAAAAAAAAGI/m90x9uPCnRQ/s1600-h/P03-F07.gif"&gt;&lt;img style="cursor: pointer; width: 318px; height: 400px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SSRVbno9i4I/AAAAAAAAAGI/m90x9uPCnRQ/s400/P03-F07.gif" alt="" id="BLOGGER_PHOTO_ID_5270431396915940226" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Infelizmente, por falhas técnicas do blog, não está sendo possível fazer upload da imagem que utilizei como fundo. Mas basta você criar qualquer imagem de 600x1 px e pintar um pixel preto no lugar correto. Veja como fazer isso no vídeo, utilizando o GIMP.&lt;br /&gt;&lt;br /&gt;Você verá que a imagem também ficará como fundo da DIV "topo", o que não é o que queremos.&lt;br /&gt;&lt;br /&gt;Para solucionar isso basta colocar uma cor de fundo na DIV topo, como faço na figura abaixo (aproveitei também para retirar a cor do fundo do menu e do conteúdo).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SSRWPsEIDcI/AAAAAAAAAGQ/ccNdG-8bti0/s1600-h/P03-F08.gif"&gt;&lt;img style="cursor: pointer; width: 315px; height: 400px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SSRWPsEIDcI/AAAAAAAAAGQ/ccNdG-8bti0/s400/P03-F08.gif" alt="" id="BLOGGER_PHOTO_ID_5270432291456814530" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora estamos perto de terminar.&lt;br /&gt;O resultado já está bem parecido com o desejado, mas o texto ainda está muito próximo das bordas. Para solucionar isso adicionarei 10px de padding a cada uma das 3 DIV's internas.&lt;br /&gt;&lt;br /&gt;Ao adicionar o padding você terá de remover 20 px tanto da altura da DIV topo, quanto da largura das DIV's menu e conteúdo, pois senão os novos tamanhos empurrarão a estrutura do nosso site.&lt;br /&gt;&lt;br /&gt;Veja como ficou na figura abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SSRYK1qPoEI/AAAAAAAAAGY/aOMwVVLPuIY/s1600-h/P03-F09.gif"&gt;&lt;img style="cursor: pointer; width: 321px; height: 400px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SSRYK1qPoEI/AAAAAAAAAGY/aOMwVVLPuIY/s400/P03-F09.gif" alt="" id="BLOGGER_PHOTO_ID_5270434407156523074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora só falta ajustarmos um detalhe.&lt;br /&gt;No último post sobre o assunto fizemos todo um trabalho para que o DIV principal acompanhasse o conteúdo do site caso ele fosse maior que a janela. Como utilizamos as propriedades float no DIV menu e conteúdo, eles não empurrarão mais a DIV principal (coloque bastante texto dentro do DIV conteúdo fazendo com que ele ultrapasse o tamanho da janela, na vertical, para conferir).&lt;br /&gt;&lt;br /&gt;Para solucionar isso vamos fazer uma "gambiarra". Colocaremos depois da div conteúdo uma nova DIV chamada "rodape", que será invisível.&lt;br /&gt;&lt;br /&gt;Colocaremos um novo bloco no CCS referente a DIV rodapé colocando a propriedade "clear" dela como "both".&lt;br /&gt;&lt;br /&gt;Sendo assim a DIV invisível rodapé será posicionada abaixo do menu e do conteúdo e, como ela não tem float, ela empurrará a DIV principal!&lt;br /&gt;&lt;br /&gt;Veja código abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SSRZlS7k1UI/AAAAAAAAAGg/o8fw7HBIlu4/s1600-h/P03-F10.gif"&gt;&lt;img style="cursor: pointer; width: 308px; height: 400px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SSRZlS7k1UI/AAAAAAAAAGg/o8fw7HBIlu4/s400/P03-F10.gif" alt="" id="BLOGGER_PHOTO_ID_5270435961202070850" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;E assim, finalmente chegamos ao resultado proposto!&lt;br /&gt;&lt;br /&gt;Mais pra frente podermos criar um quarto post extra, ensinando a criar um rodapé de verdade, que fique posicionado sempre no fundo da janela.&lt;br /&gt;&lt;br /&gt;Por enquanto é isso, espero ter ajudado!&lt;br /&gt;&lt;br /&gt;Abraços!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links relacionados:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=9TIGHvVwx18"&gt;http://www.youtube.com/watch?v=9TIGHvVwx18&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2946024586193720618?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2946024586193720618/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2946024586193720618' title='8 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2946024586193720618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2946024586193720618'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/11/layout-css-aula-3-alinhando-um-div.html' title='Layout CSS, Aula 3 - Alinhando um DIV a esquerda do outro'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/SSRKgL_7mWI/AAAAAAAAAFQ/R960i6_R2BE/s72-c/P03-F01.gif' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8186843419922604073</id><published>2008-11-17T16:22:00.007-02:00</published><updated>2008-11-17T17:16:04.980-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Recuperar valor do auto incremento após efetuar INSERT com PHP e MySQL</title><content type='html'>Saudações a todos,&lt;br /&gt;&lt;br /&gt;As vezes quando temos uma tabela no banco de dados com um campo definido como AUTO_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;INCREMENT&lt;/span&gt;, precisamos recuperar esse valor logo após o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;INSERT&lt;/span&gt; (por diversos motivos).&lt;br /&gt;&lt;br /&gt;Para isso não basta fazer uma consulta para recuperar o maior valor (MAX) do campo na tabela pois uma outra pessoa pode já ter feito um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;INSERT&lt;/span&gt; após o seu e o valor que o SQL retornará estará &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;incorreto&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Para solucionar esse problema no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;PHP&lt;/span&gt; é bem fácil, utilizamos a função &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;mysql&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;insert&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;id&lt;/span&gt;()&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Ela retorna o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;ID&lt;/span&gt; gerado por um campo de auto incremento do consulta &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;INSERT&lt;/span&gt; anterior.&lt;br /&gt;&lt;br /&gt;Por exemplo, vou inserir um registro em uma tabela chamada &lt;span style="font-weight: bold;"&gt;pedidos&lt;/span&gt; e, após isso, exibir qual foi o número do pedido gerado:&lt;br /&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');&lt;br /&gt;&lt;br /&gt;if (!$link) {&lt;br /&gt;die('Não foi possível conectar: ' . mysql_error());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;mysql_select_db('mydb');&lt;br /&gt;&lt;br /&gt;$sql = 'INSERT INTO pedidos (item, valor) VALUES (2, 200.25)';&lt;br /&gt;&lt;br /&gt;mysql_query($sql);&lt;br /&gt;&lt;br /&gt;echo 'Número do pedido: ' . mysql_insert_id();&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;br /&gt;Espero ter ajudado, qualquer dúvida poste um comentário ou me envie um e-mail (deixei meu e-mail disponível no meu perfil do blog).&lt;br /&gt;&lt;br /&gt;Abraços.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;Links&lt;/span&gt; relacionados:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.php.net/mysql_insert_id"&gt;http://www.php.net/mysql_insert_id&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8186843419922604073?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8186843419922604073/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8186843419922604073' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8186843419922604073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8186843419922604073'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/11/recuperar-valor-do-auto-incremento-aps.html' title='Recuperar valor do auto incremento após efetuar INSERT com PHP e MySQL'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-6678262283884664106</id><published>2008-11-07T21:34:00.004-02:00</published><updated>2008-11-07T21:41:39.655-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Copiar e colar textos no console do Linux</title><content type='html'>Saudações pessoal,&lt;br /&gt;&lt;br /&gt;Sei que estou devendo o terceiro &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;post&lt;/span&gt; do assunto sobre o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;layout&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;CSS&lt;/span&gt;, devo estar postando ele nos próximos dias.&lt;br /&gt;&lt;br /&gt;Hoje vou fazer um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;post&lt;/span&gt; rápido que pode ser útil. Em algumas distribuições do Linux as teclas de atalho&lt;span style="font-weight: bold;"&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;CTRL&lt;/span&gt; + C&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;CTRL&lt;/span&gt; + V &lt;/span&gt;não funcionam no &lt;span style="font-weight: bold;"&gt;console&lt;/span&gt; (&lt;span style="font-weight: bold;"&gt;Shell&lt;/span&gt;). Até existem teclas de atalho específicas para isso, mas variam em cada distribuição.&lt;br /&gt;&lt;br /&gt;Existe um jeito de &lt;span style="font-weight: bold;"&gt;copiar e colar texto no console do Linux&lt;/span&gt; (e também nos demais aplicativos dele) que funciona na maioria das distribuições. Para isso basta &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;selecionar&lt;/span&gt; o texto desejado e clicar sobre ele com o &lt;span style="font-weight: bold;"&gt;botão do&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;scroll&lt;/span&gt; do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;mouse&lt;/span&gt;&lt;/span&gt; (com isso você copia o texto) e, para colar, basta &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;selecionar&lt;/span&gt; o local desejado e clicar novamente no botão do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;scroll&lt;/span&gt;. É um jeito simples e prático de se trabalhar no Linux.&lt;br /&gt;&lt;br /&gt;Lembrando que nem sempre o texto copiado pelo &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;CTRL&lt;/span&gt; + C&lt;/span&gt; pode ser colado a  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;partir&lt;/span&gt; do botão de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;scroll&lt;/span&gt;, e &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;vice&lt;/span&gt; versa, pois cada comando utiliza uma área diferente para armazenar a informação. Mas o texto copiado pelo botão do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;scroll&lt;/span&gt; sempre pode ser colado pressionando o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;scroll&lt;/span&gt; novamente.&lt;br /&gt;&lt;br /&gt;Espero que a dica seja útil.&lt;br /&gt;&lt;br /&gt;Abraços!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-6678262283884664106?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/6678262283884664106/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=6678262283884664106' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6678262283884664106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/6678262283884664106'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/11/copiar-e-colar-textos-no-console-do.html' title='Copiar e colar textos no console do Linux'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-4382442921766276218</id><published>2008-10-30T23:17:00.003-02:00</published><updated>2008-10-30T23:36:45.949-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Atualizar Ubuntu 8.04 para 8.10</title><content type='html'>Pessoal,&lt;br /&gt;&lt;br /&gt;Foi lançada a nova versão do Ubuntu (Ubuntu 8.10) no site &lt;a href="http://www.ubuntu.com/"&gt;http://www.ubuntu.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O Ubuntu 8.04 não dará a opção de atualizar versão por padrão, então, para atualizar o seu Ubuntu 8.04 para a versão 8.10, faça o seguinte:&lt;br /&gt;&lt;br /&gt;Acesse no menu:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sistema -&gt; Administração -&gt; Canais de Software&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Acesse a aba "&lt;span style="font-weight: bold;"&gt;Atualizações&lt;/span&gt;" e mude a opção "&lt;span style="font-weight: bold;"&gt;Atualização de lançamento&lt;/span&gt;" para "&lt;span style="font-weight: bold;"&gt;versões normais&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;Feche e acesse no menu:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sistema -&gt; Administração -&gt; &lt;/span&gt;&lt;span style="font-weight: bold;" class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Gerenciador&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; de &lt;/span&gt;&lt;span style="font-weight: bold;" class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;atualizações&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A opção de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;atualizar&lt;/span&gt; para a versão 8.10 aparecerá para você.&lt;br /&gt;&lt;br /&gt;Abraços, espero ter ajudado!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-4382442921766276218?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/4382442921766276218/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=4382442921766276218' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4382442921766276218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/4382442921766276218'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/10/atualizar-ubuntu-804-para-810.html' title='Atualizar Ubuntu 8.04 para 8.10'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8960168020477692107</id><published>2008-10-25T20:11:00.010-02:00</published><updated>2008-10-29T00:05:40.633-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='video aula'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Layout CSS, Aula 2 - Altura do DIV ocupando 100% da página</title><content type='html'>Saudações,&lt;br /&gt;&lt;br /&gt;Vamos dar continuidade à criação de uma estrutura para uma página web utilizando &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;CSS&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;No último &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;post&lt;/span&gt; nós criamos a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;DIV&lt;/span&gt; principal e alinhamos no centro da página.&lt;br /&gt;Agora vamos fazer com que essa &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;DIV&lt;/span&gt; ocupe 100% da página na vertical.&lt;br /&gt;&lt;br /&gt;Segue abaixo um vídeo que eu criei explicando, na prática, como fazer.&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Acw53GhX3Tg&amp;amp;hl=pt-br&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;embed src="http://www.youtube.com/v/Acw53GhX3Tg&amp;amp;hl=pt-br&amp;amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Agora vou explicar passo a passo como foi feito.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Onde paramos.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Bom, para relembrar, o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Layout&lt;/span&gt; da página web que estamos tentando montar com &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;CSS&lt;/span&gt; seguirá a estrutura abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SQTT5XYOY3I/AAAAAAAAAEg/y0e1LyTMnLI/s1600-h/layout.gif"&gt;&lt;img style="cursor: pointer; width: 322px; height: 242px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SQTT5XYOY3I/AAAAAAAAAEg/y0e1LyTMnLI/s400/layout.gif" alt="" id="BLOGGER_PHOTO_ID_5261563247157207922" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;O código até onde nós já fizemos é o seguinte:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SQTVy8FcMzI/AAAAAAAAAEo/uxt0a4GcCEQ/s1600-h/css1-04.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 329px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SQTVy8FcMzI/AAAAAAAAAEo/uxt0a4GcCEQ/s400/css1-04.gif" alt="" id="BLOGGER_PHOTO_ID_5261565335774704434" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Como dito antes, nós já temos a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;DIV&lt;/span&gt; principal e ela já está alinha no centro da página.&lt;br /&gt;&lt;br /&gt;Para utilizar o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;CSS&lt;/span&gt; de forma mais adequada, eu substituí o parâmetro &lt;span style="font-weight: bold;"&gt;"&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;class&lt;/span&gt;"&lt;/span&gt;, do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;tag&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;DIV&lt;/span&gt;&lt;/span&gt; por &lt;span style="font-weight: bold;"&gt;"&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;id&lt;/span&gt;"&lt;/span&gt;. Pois como o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;CSS&lt;/span&gt; que será definido para a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;DIV&lt;/span&gt; principal será utilizado apenas nela, podemos então usar &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;id&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Para fazer essa alteração, tive que alterar, também, o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;seletor&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;"."&lt;/span&gt; (ponto) do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;CSS&lt;/span&gt; por &lt;span style="font-weight: bold;"&gt;"#"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Conforme figura abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SQTXaovRTKI/AAAAAAAAAEw/S4ljL0CvlNw/s1600-h/CSS20.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 331px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SQTXaovRTKI/AAAAAAAAAEw/S4ljL0CvlNw/s400/CSS20.gif" alt="" id="BLOGGER_PHOTO_ID_5261567117287836834" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Definindo a altura da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;tag&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para definir a altura de uma &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;tag&lt;/span&gt; utilizamos a propriedade &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;height&lt;/span&gt;&lt;/span&gt; (altura).&lt;br /&gt;Em tese, tudo que deveríamos fazer para nossa &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;DIV&lt;/span&gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;principal&lt;/span&gt; ocupar 100% do navegador seria colocar sua propriedade &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;height&lt;/span&gt; como 100% (&lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;height&lt;/span&gt;: 100%;&lt;/span&gt;).&lt;br /&gt;Mas isso não será o suficiente, vou explicar o porque.&lt;br /&gt;&lt;br /&gt;Ao utilizar &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;porcentagem&lt;/span&gt;&lt;/span&gt; como parâmetro para a propriedade &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;height&lt;/span&gt;&lt;/span&gt;, estamos definindo o quanto da altura da &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;tag&lt;/span&gt; pai&lt;/span&gt; estaremos ocupando.&lt;br /&gt;Se você reparar, a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;tag&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;DIV&lt;/span&gt;&lt;/span&gt; está dentro da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;tag&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;BODY&lt;/span&gt;&lt;/span&gt;, que por sua vez está dentro da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;tag&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;HTML&lt;/span&gt;. Então &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;height&lt;/span&gt;: 100%&lt;/span&gt; na &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;tag&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;DIV&lt;/span&gt;&lt;/span&gt; quer dizer que ela utilizará toda a altura disponível dentro da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;tag&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;BODY&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;Como a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;tag&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;BODY&lt;/span&gt;&lt;/span&gt; não tem uma altura definida, ela recebe por padrão o valor &lt;span style="font-weight: bold;"&gt;"auto"&lt;/span&gt;, que quer dizer que ela usará a altura necessária para envolver os textos, imagens, etc dentro de suas &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;tags&lt;/span&gt; filhotes&lt;/span&gt;. Portanto, a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;tag&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;DIV&lt;/span&gt;&lt;/span&gt; não conseguirá utilizar muito espaço dessa forma.&lt;br /&gt;Para chegar ao resultado que queremos devemos definir, além da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;DIV&lt;/span&gt;, a altura da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;BODY&lt;/span&gt; e da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;tag&lt;/span&gt; HTML como 100%, assim a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;DIV&lt;/span&gt; conseguirá utilizar 100% da página.&lt;br /&gt;&lt;br /&gt;A figura abaixo ilustra essa situação:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SQe3_hwWdCI/AAAAAAAAAE4/DiWAdarJVW4/s1600-h/explicacao.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 215px;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SQe3_hwWdCI/AAAAAAAAAE4/DiWAdarJVW4/s400/explicacao.gif" alt="" id="BLOGGER_PHOTO_ID_5262376991626523682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;E essa outra figura demonstra como ficou o código até agora, com as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;tags&lt;/span&gt; HTML, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;BODY&lt;/span&gt; e &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;DIV&lt;/span&gt; (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;id&lt;/span&gt;='principal') com altura 100% (inseri cores de fundo para ficar mais fácil a visualização e bordas esquerda e direita, retirei a borda total):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SQe6jHLW3LI/AAAAAAAAAFA/TB1emtgzVfA/s1600-h/css2-x1.gif"&gt;&lt;img style="cursor: pointer; width: 372px; height: 400px;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SQe6jHLW3LI/AAAAAAAAAFA/TB1emtgzVfA/s400/css2-x1.gif" alt="" id="BLOGGER_PHOTO_ID_5262379801990585522" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Definindo a altura mínima (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;min&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;height&lt;/span&gt;).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Nosso código já está bem próximo do efeito esperado, mas ele ainda possui uma falha (que não será percebida se você estiver utilizando &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;Internet&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_55"&gt;Explorer&lt;/span&gt; 6 ou inferior).&lt;br /&gt;&lt;br /&gt;Se digitarmos muito texto dentro da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;DIV&lt;/span&gt; a ponto de que o texto exceda a altura dela, perceberemos que o navegador expande sua área de visualização mas a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_58"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;DIV&lt;/span&gt; não acompanha, então parte do texto ficará fora da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;tag&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Para fazer com que a altura da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_61"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_62"&gt;DIV&lt;/span&gt; acompanhe o texto dentro dela, precisamos definir a propriedade &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_63"&gt;height&lt;/span&gt;&lt;/span&gt; da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_64"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_65"&gt;DIV&lt;/span&gt; principal como "&lt;span style="font-weight: bold;"&gt;auto&lt;/span&gt;" (&lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_66"&gt;height&lt;/span&gt;: auto;&lt;/span&gt;).&lt;br /&gt;Mas, ao fazer isso, nossa &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_67"&gt;tag&lt;/span&gt; deixará de ocupar 100% da altura do navegador.&lt;br /&gt;&lt;br /&gt;Para fazer com que ela volte a ocupar 100% do navegador e continue acompanhando o texto caso ele seja maior do que ela, podemos utilizar a propriedade &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_68"&gt;min&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_69"&gt;height&lt;/span&gt;&lt;/span&gt; (altura mínima).&lt;br /&gt;&lt;br /&gt;Se definirmos &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_70"&gt;min&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_71"&gt;height&lt;/span&gt;: 100% e &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_72"&gt;height&lt;/span&gt;: auto estaremos fazendo com que a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_73"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_74"&gt;DIV&lt;/span&gt; ocupe, no mínimo, 100% da altura inicial e, caso o texto ultrapasse essa altura, ela o acompanhe.&lt;br /&gt;&lt;br /&gt;Seria perfeito se não fosse pelo fato de que o &lt;span style="font-weight: bold;"&gt;Internet &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_75"&gt;Explorer&lt;/span&gt; não reconhece, ainda, a propriedade &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_76"&gt;min&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_77"&gt;height&lt;/span&gt; do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_78"&gt;CSS&lt;/span&gt;&lt;/span&gt; (a maioria dos demais navegadores já trabalham com ela).&lt;br /&gt;&lt;br /&gt;Para solucionar o problema eu encontrei dois métodos.&lt;br /&gt;&lt;br /&gt;O primeiro seria utilizar a propriedade &lt;span style="font-weight: bold;"&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_79"&gt;height&lt;/span&gt;: 100%&lt;/span&gt;;&lt;br /&gt;Que funciona como uma espécie de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_80"&gt;hack&lt;/span&gt; para adicionar altura mínima no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_81"&gt;Internet&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_82"&gt;Explorer&lt;/span&gt;. Mas eu ouvi comentários de que essa propriedade não é reconhecida pelo W3C, então você não conseguirá validar seu código &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_83"&gt;CSS&lt;/span&gt; se estiver utilizando ela.&lt;br /&gt;&lt;br /&gt;Outra seria utilizar o código abaixo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;* html #principal {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;     &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_84"&gt;height&lt;/span&gt;: 100%;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Que define altura como 100% &lt;span style="font-weight: bold;"&gt;apenas&lt;/span&gt; para o navegador Internet &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_85"&gt;Explorer&lt;/span&gt;. Parece que existe uma convenção de que, ao utilizarmos o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_86"&gt;seletor&lt;/span&gt; "* html" estamos nos referindo a propriedades que só serão utilizadas pelo Internet &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_87"&gt;Explorer&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Bom, sendo assim, segue abaixo nosso código final:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SQe_VdA2EII/AAAAAAAAAFI/FJdZChBCVxA/s1600-h/css2-x2.gif"&gt;&lt;img style="cursor: pointer; width: 328px; height: 400px;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SQe_VdA2EII/AAAAAAAAAFI/FJdZChBCVxA/s400/css2-x2.gif" alt="" id="BLOGGER_PHOTO_ID_5262385064892043394" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Bom, por enquanto é só.&lt;br /&gt;Já temos nossa &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_88"&gt;DIV&lt;/span&gt; principal &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_89"&gt;alinhada&lt;/span&gt; no centro da página e utilizando 100% da altura disponível no navegador.&lt;br /&gt;No próximo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_90"&gt;post&lt;/span&gt; sobre o assunto faremos as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_91"&gt;DIV&lt;/span&gt;'s internas, ensinando como alinhar uma ao lado da outra e, também, utilizaremos a técnica chamada &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_92"&gt;faux&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_93"&gt;columns&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Até lá!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links relacionados:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=Acw53GhX3Tg"&gt;http://www.youtube.com/watch?v=Acw53GhX3Tg&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8960168020477692107?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8960168020477692107/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8960168020477692107' title='12 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8960168020477692107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8960168020477692107'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/10/layout-css-aula-2-altura-do-div.html' title='Layout CSS, Aula 2 - Altura do DIV ocupando 100% da página'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/SQTT5XYOY3I/AAAAAAAAAEg/y0e1LyTMnLI/s72-c/layout.gif' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2504657474030401615</id><published>2008-10-20T22:46:00.011-02:00</published><updated>2008-10-29T00:00:26.019-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><category scheme='http://www.blogger.com/atom/ns#' term='video aula'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Layout CSS, Aula 1 - Como alinhar um DIV no centro da página</title><content type='html'>Saudações,&lt;br /&gt;&lt;br /&gt;A proposta nesse tópico é ensinar como criar um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;layout&lt;/span&gt; simples para uma página web utilizando &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;CSS&lt;/span&gt;.&lt;br /&gt;O resultado final será um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;layout&lt;/span&gt; com uma estrutura similar a da figura abaixo:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SP0oSweeQnI/AAAAAAAAADw/C3pxyvNerWc/s1600-h/layout.gif"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SP0oSweeQnI/AAAAAAAAADw/C3pxyvNerWc/s400/layout.gif" alt="" id="BLOGGER_PHOTO_ID_5259404242554077810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Onde temos um espaço na parte superior para o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;logotipo&lt;/span&gt;, outro na parte inferior esquerda para o menu e outro para o conteúdo.&lt;br /&gt;&lt;br /&gt;Para fazer isso utilizarei três &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;posts&lt;/span&gt;, cada um com um assunto específico.&lt;br /&gt;&lt;br /&gt;O assunto deste primeiro &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;post&lt;/span&gt; será &lt;span style="font-weight: bold;"&gt;"Como alinhar um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;DIV&lt;/span&gt; no centro da página"&lt;/span&gt;.&lt;br /&gt;Onde criaremos o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;DIV&lt;/span&gt; principal que &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_8"&gt;conterá&lt;/span&gt; toda a estrutura do site dentro dele.&lt;br /&gt;&lt;br /&gt;Para ajudar no entendimento gravei um vídeo, mas mesmo assim vou colocar abaixo as instruções passo a passo, pois nem sempre da pra ler no vídeo os textos.&lt;br /&gt;&lt;br /&gt;Segue abaixo o vídeo:&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Hwm4icfhhvw&amp;amp;hl=pt-br&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;embed src="http://www.youtube.com/v/Hwm4icfhhvw&amp;amp;hl=pt-br&amp;amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;E agora vamos ao tutorial:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Criando a estrutura básica.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Primeiramente eu criei a estrutura simples de um HTML e &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_9"&gt;inseri&lt;/span&gt; um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;DIV&lt;/span&gt; com a classe &lt;span style="font-weight: bold;"&gt;'principal'&lt;/span&gt; dentro do corpo da página (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;body&lt;/span&gt;).&lt;br /&gt;Criei um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;CSS&lt;/span&gt; para se referir a esse &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;DIV&lt;/span&gt; adicionando borda e largura a ele, o código ficou assim:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SP0sAvJPU5I/AAAAAAAAAEA/2s7GkyImPsU/s1600-h/css1-01.gif"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SP0sAvJPU5I/AAAAAAAAAEA/2s7GkyImPsU/s400/css1-01.gif" alt="" id="BLOGGER_PHOTO_ID_5259408331005449106" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Eliminando espaços entre o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;DIV&lt;/span&gt; principal e o corpo da página.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Com isso &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_15"&gt;já&lt;/span&gt; temos o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;DIV&lt;/span&gt;, vamos agora ajustar a margem do corpo da página para não haver espaço entre o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;DIV&lt;/span&gt; e o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;BODY&lt;/span&gt;.&lt;br /&gt;Para isso vou adicionar um novo bloco &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;CSS&lt;/span&gt;, definindo a margem para a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;body&lt;/span&gt; como 0&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;px&lt;/span&gt;.&lt;br /&gt;Conforme figura abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CGnpveaIy_M/SP0tVAERLNI/AAAAAAAAAEI/tLzs8Coq-4c/s1600-h/css1-02.gif"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_CGnpveaIy_M/SP0tVAERLNI/AAAAAAAAAEI/tLzs8Coq-4c/s400/css1-02.gif" alt="" id="BLOGGER_PHOTO_ID_5259409778657012946" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora tudo que nos resta fazer nesta primeira lição é alinhar o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;DIV&lt;/span&gt; no centro da página.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Alinhando o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;DIV&lt;/span&gt; no centro.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para isso. em &lt;span style="font-weight: bold;"&gt;alguns navegadores&lt;/span&gt;, basta definir o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;body&lt;/span&gt; com &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;text&lt;/span&gt;-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;align&lt;/span&gt;&lt;/span&gt; igual a &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;center&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;Isso funciona em algumas versões do Internet &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;Explorer&lt;/span&gt;, segue exemplo na figura alinhei o texto dentro do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;body&lt;/span&gt; como centralizado e, dentro da &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;tag&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;div&lt;/span&gt;, tornei a alinhá-lo a esquerda):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SP0u5QnXiMI/AAAAAAAAAEQ/2eCUfpHDsi0/s1600-h/css1-03.gif"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SP0u5QnXiMI/AAAAAAAAAEQ/2eCUfpHDsi0/s400/css1-03.gif" alt="" id="BLOGGER_PHOTO_ID_5259411501086116034" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;O código acima ainda não funciona em alguns navegadores, para solucionar esse problema o truque será adicionar &lt;span style="font-weight: bold;"&gt;margens automáticas&lt;/span&gt; ao &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;div&lt;/span&gt; principal (&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_35"&gt;margem&lt;/span&gt; esquerda e direita), como mostra a figura abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CGnpveaIy_M/SP0wHSZWHaI/AAAAAAAAAEY/rsDflUkmeJs/s1600-h/css1-04.gif"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_CGnpveaIy_M/SP0wHSZWHaI/AAAAAAAAAEY/rsDflUkmeJs/s400/css1-04.gif" alt="" id="BLOGGER_PHOTO_ID_5259412841593970082" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pronto!&lt;br /&gt;Com isso já teremos nosso &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;DIV&lt;/span&gt; alinhado no centro da página!&lt;br /&gt;&lt;br /&gt;Por enquanto vou ficando por aqui, espero ter ajudado!&lt;br /&gt;Criarei mais dois &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;posts&lt;/span&gt; sobre o assunto para concluir a estrutura do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;layout&lt;/span&gt; &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_39"&gt;mencionada&lt;/span&gt; no começo do tópico, serão eles:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://brunograsselli.com.br/2008/10/layout-css-aula-2-altura-do-div.html"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;Layout&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;CSS&lt;/span&gt;, Aula 2 - Altura do &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;DIV&lt;/span&gt; ocupando 100% da página&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;Layout&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;CSS&lt;/span&gt;, Aula 3 - Alinhando um &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;DIV&lt;/span&gt; a esquerda do outro&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Até lá!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links relacionados:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=Hwm4icfhhvw"&gt;http://www.youtube.com/watch?v=Hwm4icfhhvw&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2504657474030401615?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2504657474030401615/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2504657474030401615' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2504657474030401615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2504657474030401615'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/10/layout-css-aula-1-como-alinhar-um-div.html' title='Layout CSS, Aula 1 - Como alinhar um DIV no centro da página'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CGnpveaIy_M/SP0oSweeQnI/AAAAAAAAADw/C3pxyvNerWc/s72-c/layout.gif' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-407570006156578902</id><published>2008-10-19T23:26:00.004-02:00</published><updated>2008-10-19T23:41:36.432-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Configurar Ubuntu 8.04 para resolução 1024 x 768</title><content type='html'>Saudações mais uma vez,&lt;br /&gt;&lt;br /&gt;Quando instalei o Ubuntu pela primeira vez (&lt;span style="font-weight: bold;"&gt;versão 7.04&lt;/span&gt;) não havia conseguido configurá-lo para trabalhar com a resolução &lt;span style="font-weight: bold;"&gt;1024 x 768&lt;/span&gt; do monitor.&lt;br /&gt;Quando lançou a &lt;span style="font-weight: bold;"&gt;versão 8.04&lt;/span&gt; instalei ele de novo e, novamente, a máxima resolução que eu conseguia era &lt;span style="font-weight: bold;"&gt;800 x 600&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Tentei alterar o arquivo &lt;span style="font-weight: bold;"&gt;xorg.conf&lt;/span&gt; e também utilizar aquele comando que configura uma série de dispositivos via shell mas nada feito.&lt;br /&gt;&lt;br /&gt;Foi então que encontrei em um fórum um comando que solucionou meus problemas, portanto, se você está enfrentando a mesma situação, tente o seguinte comando para configurar a placa de vídeo e o monitor:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# sudo displayconfig-gtk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;No meu caso, foi só ajustar o monitor e a opção de 1024 x 768 já ficou disponível.&lt;br /&gt;&lt;br /&gt;Segue abaixo o link onde consegui o comando:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ubuntuforum-br.org/index.php?topic=35834.0"&gt;http://ubuntuforum-br.org/index.php?topic=35834.0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[]s!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-407570006156578902?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/407570006156578902/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=407570006156578902' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/407570006156578902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/407570006156578902'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/10/configurar-ubuntu-804-para-resoluo-1024.html' title='Configurar Ubuntu 8.04 para resolução 1024 x 768'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2377117532583629132</id><published>2008-10-18T18:16:00.002-03:00</published><updated>2008-10-18T18:24:44.167-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Ubuntu 8.10 será lançado em breve</title><content type='html'>Saudações a todos,&lt;br /&gt;&lt;br /&gt;Estava dando uma olhada em alguns sites na &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;internet&lt;/span&gt; e descobri que dia 30 de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;outubro&lt;/span&gt; será lançada a nova versão do &lt;a href="http://www.ubuntu.com"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Ubuntu&lt;/span&gt;&lt;/a&gt;! O &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Ubuntu&lt;/span&gt; 8.10.&lt;br /&gt;Já está disponível a versão beta para &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;download&lt;/span&gt; no endereço:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ubuntu.com/testing/intrepid/beta"&gt;http://www.ubuntu.com/testing/intrepid/beta&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Vou aguardar &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;ansiosamente&lt;/span&gt; pela versão final!&lt;br /&gt;&lt;br /&gt;Enquanto isso, coloquei o contador com a contagem regressiva para o lançamento no menu do blog. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Faça&lt;/span&gt; isso no seu site também e ajude a divulgar, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;acessando&lt;/span&gt; o endereço:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ubuntu.com/getubuntu/countdown"&gt;http://www.ubuntu.com/getubuntu/countdown&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[]s!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2377117532583629132?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2377117532583629132/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2377117532583629132' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2377117532583629132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2377117532583629132'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/10/ubuntu-810-ser-lanado-em-breve.html' title='Ubuntu 8.10 será lançado em breve'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-7608448837640009501</id><published>2008-10-16T20:46:00.008-03:00</published><updated>2008-10-19T23:47:31.661-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='evento'/><title type='text'>Open Hack 2008 - Yahoo! Brasil</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CGnpveaIy_M/SPfWAQPb9AI/AAAAAAAAADo/n91ETn4NTds/s1600-h/open-hack-recap.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_CGnpveaIy_M/SPfWAQPb9AI/AAAAAAAAADo/n91ETn4NTds/s400/open-hack-recap.png" alt="" id="BLOGGER_PHOTO_ID_5257906389826401282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Dias 8 e 9 de novembro vai acontecer no Centro Universitário Senac, campus Santo Amaro (SP), o Hack Day da Yahoo! Brasil.&lt;br /&gt;&lt;br /&gt;Segue abaixo texto do panfleto:&lt;br /&gt;&lt;br /&gt;"&lt;span style="font-weight: bold;"&gt;O que é?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O Yahoo! Open Hack Day é um encontro de desenvolvedores e estudantes de TI promovido pelo Yahoo! Brasil.&lt;br /&gt;Durante dois dias sem intervalos, os participantes estarão reunidos em uma grande celebração para exercitar suas mentes, criar novos aplicativos e serviços baseados nas plataformas do Yahoo! e ampliar suas redes de contatos.&lt;br /&gt;&lt;br /&gt;Serão 24 horas seguidas de muito trabalho e diversão que vão premiar os autores dos melhores projetos e quatro categorias:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;BOSS:&lt;/span&gt;&lt;br /&gt;Plataforma aberta de web services do Yahoo! Search para você construir produtos de busca com base na indexação do Yahoo!&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;SEARCHMONKEY:&lt;/span&gt;&lt;br /&gt;Nova plataforma aberta do Yahoo! Search, para você usar dados estruturados, conhecidos como micro formatos, e tornar os resultados do Yahoo! Search do jeito que você quiser.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;YAHOO! BLUEPRINT MOBILE:&lt;/span&gt;&lt;br /&gt;Plataforma de criação de widgets para celulares com suporte a múltiplos dispositivos e sistemas operacionais.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;CATEGORIA LIVRE:&lt;/span&gt;&lt;br /&gt;Use a imaginação e crie um projeto inovador usando os recursos  de todas as plataformas do Yahoo!"&lt;/li&gt;&lt;/ul&gt;Esse evento é inédito na América Latina.&lt;br /&gt;&lt;br /&gt;Endereço: Av. Engenheiro Eusébio Stevaux, 823 (altura do número 22.200 da Av. Nações Unidas).&lt;br /&gt;&lt;br /&gt;Inscreva-se em &lt;a href="http://hackday.org/"&gt;HACKDAY.ORG&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sites relacionados:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://hackday.org/"&gt;http://hackday.org&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://developer.yahoo.com/"&gt;http://developer.yahoo.com&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-7608448837640009501?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/7608448837640009501/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=7608448837640009501' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7608448837640009501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/7608448837640009501'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/10/open-hack-2008-yahoo-brasil.html' title='Open Hack 2008 - Yahoo! Brasil'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CGnpveaIy_M/SPfWAQPb9AI/AAAAAAAAADo/n91ETn4NTds/s72-c/open-hack-recap.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2484140607289170412</id><published>2008-10-14T21:46:00.007-03:00</published><updated>2008-10-14T22:33:17.397-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Configurando o GRUB, gerenciador de boot do Linux</title><content type='html'>Bom, vamos dizer que você instalou o Linux mas gostaria que o Windows ainda ficasse como a opção padrão na hora de iniciar o computador (boot).&lt;br /&gt;&lt;br /&gt;Na maioria das distribuições Linux, o programa que é utilizado para gerenciar a inicialização do computador (qual sistema irá iniciar, etc) é ou o &lt;span style="font-weight: bold;"&gt;GRUB&lt;/span&gt;, ou o &lt;span style="font-weight: bold;"&gt;Lilo&lt;/span&gt;.&lt;br /&gt;Nesse post vou mostrar como configurar a tela de menu do GRUB (imagem abaixo).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CGnpveaIy_M/SPVAGQ87UEI/AAAAAAAAADg/TGZjv9BP9ks/s1600-h/GRUB_screenshot.png"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_CGnpveaIy_M/SPVAGQ87UEI/AAAAAAAAADg/TGZjv9BP9ks/s400/GRUB_screenshot.png" alt="" id="BLOGGER_PHOTO_ID_5257178616398827586" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para editar a tela de menu do GRUB é bem simples, basta editar o arquivo (precisará de permissões de administrador):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;/boot/grub/menu.lst&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para isso, basta usar qualquer editor de texto, por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# sudo gedit /boot/grub/menu.lst&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ou&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# sudo vim /boot/grub/menu.lst&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;No final desse arquivo você encotrará blocos de texto como estes:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;title        Microsoft Windows XP Home Edition&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;root        (hd0,0)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;savedefault&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;makeactive&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;chainloader    +1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;title        Ubuntu 8.04.1, kernel 2.6.24-19-generic&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;root        (hd0,2)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;kernel        /boot/vmlinuz-2.6.24-19-generic root=UUID=78c2a245-185e417e-8871-d5e3d6f6e4e7 ro quiet splash locale=pt_BR&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;initrd        /boot/initrd.img-2.6.24-19-generic&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;quiet&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para alterar a ordem de exibição dos itens do menu basta trocar a ordem deles no arquivo.&lt;br /&gt;&lt;br /&gt;Para escolher qual sistema operacional será o padrão na hora da inicialização você tem duas opções:&lt;br /&gt;&lt;br /&gt;A primeira é escrever a linha "&lt;span style="font-weight: bold;"&gt;savedefault&lt;/span&gt;" no sitema operacional desejado. Como estava no exemplo que eu coloquei acima.&lt;br /&gt;&lt;br /&gt;A segunda opção é alterar, la no começo do arquivo, a linha:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;default        0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Colocando o número do item que deseja definir como padrão (lembrando que a contagem começa do zero).&lt;br /&gt;&lt;br /&gt;Nesse arquivo você pode configurar também o tempo padrão para exibição do menu (em segundos), alterando o valor na linha (está localizada, geralmente, no começo do arquivo):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;timeout        10&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Após efetuar as alterações desejadas, basta salvar o arquivo (lembrando que é bom sempre fazer um back-up antes de alterar um arquivo de sistema).&lt;br /&gt;&lt;br /&gt;Espero ter ajudado,&lt;br /&gt;&lt;br /&gt;[]s.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-2484140607289170412?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/2484140607289170412/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=2484140607289170412' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2484140607289170412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/2484140607289170412'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/10/configurando-o-grub-gerenciador-de-boot.html' title='Configurando o GRUB, gerenciador de boot do Linux'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_CGnpveaIy_M/SPVAGQ87UEI/AAAAAAAAADg/TGZjv9BP9ks/s72-c/GRUB_screenshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-8616631568809271429</id><published>2008-10-11T23:20:00.008-03:00</published><updated>2008-10-18T12:16:30.218-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Converter inteiro para hexadecimal em java</title><content type='html'>Há uns tempos atrás eu estava criando um programa e precisava obter a representação hexadecimal de um número inteiro, perguntei em um fórum e as soluções que me deram eram um tanto quanto trabalhosas.&lt;br /&gt;&lt;br /&gt;Hoje eu encontrei em um livro para certificação &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;scjp&lt;/span&gt; uma solução muito simples para este problema. Na verdade, duas.&lt;br /&gt;&lt;br /&gt;Existem dois métodos estáticos das classes &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;wrapper&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Integer&lt;/span&gt;&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Long&lt;/span&gt;&lt;/span&gt; que podem te ajudar nessa tarefa, são eles:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Long&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;toString&lt;/span&gt;(255, 16);&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Long&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;toHexString&lt;/span&gt;(255);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ambos retornam um String com a representação hexadecimal do número inteiro (ou &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;long&lt;/span&gt;) informado. Como eu informei o inteiro &lt;span style="font-weight: bold;"&gt;255&lt;/span&gt; eles me retornarão &lt;span style="font-weight: bold;"&gt;"&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;ff&lt;/span&gt;"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;No caso do método &lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;toString&lt;/span&gt;()&lt;/span&gt; do exemplo, ele recebe dois parâmetros, o primeiro é o número inteiro que você deseja obter a representação em String e o segundo é a base.&lt;br /&gt;Outro exemplos utilizando esse método:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;long&lt;/span&gt; numero = 16l;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;//Base 2 - Binária&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;System.out.println(Long.toString(numero,2));&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;//Base 8 - &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Octal&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;System.out.println(Long.toString(numero,8));&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;//Base 10 - Decimal&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;System.out.println(Long.toString(numero,10));&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;//Base 16 - hexadecimal&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;System.out.println(Long.toString(numero,16));&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;Bom, espero ter ajudado, eu sei que essa dica não é útil pra muita gente, mas se alguém estiver se deparando com esse mesmo problema essa solução pode ajudar.&lt;br /&gt;&lt;br /&gt;[]s.&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9058337287611971869-8616631568809271429?l=brunograsselli.com.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://brunograsselli.com.br/feeds/8616631568809271429/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9058337287611971869&amp;postID=8616631568809271429' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8616631568809271429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9058337287611971869/posts/default/8616631568809271429'/><link rel='alternate' type='text/html' href='http://brunograsselli.com.br/2008/10/converter-inteiro-para-hexadecimal-em.html' title='Converter inteiro para hexadecimal em java'/><author><name>Bruno Grasselli</name><uri>http://www.blogger.com/profile/13396436801909306046</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9058337287611971869.post-2583807370389731613</id><published>2008-10-11T14:43:00.008-03:00</published><updated>2008-10-11T19:10:41.726-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='desenvolvimento web'/><title type='text'>Javascript para criar teclas de atalho em páginas web</title><content type='html'>Saudações a todos,&lt;br /&gt;&lt;br /&gt;Nesse post vou ensinar um modo de inserir teclas de atalho (shortcut keys) em uma página web, utilizando &lt;span style="font-weight: bold;"&gt;javascript&lt;/span&gt;. Na maioria dos casos as teclas de atalhos são muito úteis e dão maior agilidade a processos, imagine a vida sem o &lt;span style="font-weight: bold;"&gt;CTRL + C&lt;/span&gt; e &lt;span style="font-weight: bold;"&gt;CTRL + V&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;O código abaixo mostra uma mensagem de texto quando o usuário do site pressiona &lt;span style="font-weight: bold;"&gt;CTRL + A&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;script type='text/javascript'&amp;gt;&lt;br /&gt;document.onkeydown = function(e){&lt;br /&gt;var keychar;&lt;br /&gt;&lt;br /&gt;// Internet Explorer&lt;br /&gt;try {&lt;br /&gt;    keychar = String.fromCharCode(event.keyCode);&lt;br /&gt;    e = event;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Firefox,
