Archive for 'Ruby/Rails'
RVM, onde estou!?!?!
Posted on November 24, 2009, under Configuração, Desenvolvimento, Ruby/Rails.
Comecei a utilizar o RVM em sua versão 0.0.22, na época ele não passava de um script shell que permitia a instalação e troca entre as vms, mas ele vem avançado muito, e funcionalidade com set de gemas é só a ponta do iceberg.
Motivado pelo post anterior acabei lendo um pouco mais a documentação e encontrei uns scriptizinho bem interessante. Como saber rapidamente qual a versão atual da minha VM? Para isso podemos contar com o script ~/.rvm/bin/rvm-prompt, ele pode ser usando adicionando a seguinte linha ao seu .bash_profile:
Com isso ele mostra qual maquina virtual do Ruby você esta usando, mas apenas quando essa for diferente da default. Só isso já seria o suficiente, mas o que me incomoda nesta solução, é que eu já tenho uma linha de comando grande, e nem sempre eu preciso saber qual versão eu estou usando, isso é particularmente interessante quando estou em um projeto Ruby. Como normalmente um projeto Ruby temos um arquivo Rakefile podemos procurar por este arquivo e exibir a versão da máquina apenas quando estivermos no diretório de um projeto Ruby. Vamos adicionar as seguintes linhas ao nosso .bash_profile:
RVM_VERSION=`~/.rvm/bin/rvm-prompt`
if [[ -f "$(pwd)/Rakefile" ]] && [[ ! -z "$RVM_VERSION" ]]; then
echo "${RVM_VERSION} "
fi
}
Agora podemos mudar a linha anterior para:
Espero que ajude alguém e qualquer dica que possa melhor é só comentar a baixo.
Para tudo! Instale o RVM antes.
Posted on November 24, 2009, under Desenvolvimento, Ruby/Rails.
Essa era uma dica que gostaria de ter recebido antes de ter encostado no meu mac, mas infelizmente na época o RVM ainda não existia, então para quem esta começando a usar Mac OS X e principalmente Ruby, use o RVM. Digo isso porque uma vez que tenha feito a bagunça de instalar varias máquinas Ruby, a coisa vai começar a complicar.
Mas o que raios é esse RVM? Ruby Version Manager, é basicamente um instalador e gerenciador de máquinas virtuais Ruby, e adicionalmente um gerenciador de sets de gemas. Por baixos dos panos ele é um script bash que troca algumas variáveis de ambiente e permite ter varias versões das máquinas virtuais Ruby (MRI, Jruby, etc) instaladas diretamente na pasta do usuário, dessa forma ele ainda permite um isolamento entre as instalações de VMS dos usuário de uma máquina.
A grande vantagens dele esta em não misturas as coisas de uma VM com a outra, e permite uma rápida troca entra uma VM e outra. A vantagem adicional de gerência sets de gemas é na verdade um grande achado, pois juntas as duas coisas permite criar ambientes isolados por aplicação, e quem trabalha com Ruby sabe como é difícil lidar com o o esquema de gemas, famoso “DLL Hell”.
Mas vamos deixar de conversa e vamos mostrar como usar. A instalação é simples, e feita usando o gem, que no caso de você esta usando Leopard já vai estar instalado:
$ rvm-install
O segundo comando vai criar a pasta ~/.rvm, é nela que toda a magia acontece, dentre outras coisas dentro dessa pasta esta os scripts que permite o funcionamento do rvm, observe que este comando mostra uma instrução sobre como adicionar o carregamento do RVM no seu bash, isso pode variar dependendo de máquina e SO.
Uma vez que bash esteja configurado, o comando rvm deve estar disponível, sua utilização é simples:
$ rvm install ree # para instalar ruby enterprise por exemplo
$ rvm ree # passa a utilizar o ruby enterprise com máquina virtual rvm
Bom até aqui temos o bem básico, você pode ver mais sobre a instalação e configuração do RVM aqui. Agora vamos a um exemplo de para o esquema de sets de gemas. Vamos criar um set para um blog, típico não
$ rvm 1.8.7 # vamos para máquina MRI v=1.8.7 só para listar as gemas
$ gem list # veja que não há nenhuma gema instalada
$ rvm 1.8.7%blog # aqui estamos criando um novo set com base na máquina 1.8.7
$ gem install rails # vamos instalar rails nesse set
$ gem list # observe que vc tem rails instalado
$ rvm use 1.8.7 # agora não tem mais ;)
Agora é só criar sets diferentes para suas aplicações e evitar a colisão das malditas gemas. Mas antes disso duas observações importantes: Evite o uso do sudo quando for instalar a gemas dentro de uma das máquinas virtuais, elas podem ate funcionar, mas isso vai fazer com que as gemas sejam instaladas como root e os arquivos dentro de pasta ~/.rvm/** não vão pode ser removidos pelo usuário normalmente.
Outra dica que eu acho importante, mesmo ele permitindo que volte a VM default do sistema, prefira fazer uma instalação limpa dela dentro do rvm, isso permite manter as coisas separadas e facilita na hora de criar um set ou mesmo atualizar sua VM.
Limpando o console automaticamente a cada teste
Posted on April 18, 2009, under Desenvolvimento, Ruby/Rails.
Se tem uma coisa que eu sou completamente fã é do ZenTest, o autotest incluído nele é uma das melhores ferramentas para desenvolvedor Ruby hoje em dia.
Habitualmente tenho uso dois monitores para desenvolver, onde em um eu deixo o autotest rodando e no outro eu vou alterando o código no editor. Um problema é que uma vez salvo o arquivo e o autotest inicie um novo teste acaba misturando visualmente um teste com outro. No mac da para usar o command+k para limpar o boffer do terminal, mas o que não chega a ser uma solução boa, pq acabo perdendo os testes que já se passaram.
Ontem o @jcmlima deu uma idéia: “e se ele limpasse automaticamente”, hoje depois de alguns palpites do @fnando e do @willian acabei achando o um jeito de fazer isso, o esquema é editar seu ~/.autotest ou o .autotest do projeto que você gostaria que tivesse essa funcionalidade e adicionar o código a baixo:
20.times { puts }
system("clear")
end
Em resumo o resultado final é que a cada nova rodada de teste ele vai inserir 20 linhas em branco e depois limpar a tela, mas diferente da opção de command+k ele ainda vai permitir que você role a tela e possa ver os testes que se passaram.
Ordenando a lista de opções no plugin activerecord_symbolize
Posted on November 14, 2008, under Desenvolvimento, Ruby/Rails, plugins.
Ainda na continuação do post anterior, a troca de idéias com o Cássio acabaram por render mais frutos para o plugin.
Já tinha tempo que eu estava precisando de uma forma de ordenar as opções que no select ou radio gerado pelos helpers select_sym e radio_sym respectivamente. O problema era que o plugin trabalhava com o arrays simples ou com hash para estabelecer os valores possíveis para o atributo.
Bom como hash não tem um ardem certa em que os seus valores possam ser capturados, uma vez que ele seja definido, um simples each sobre o hash pode trazer seus valores em qualquer ordem.
Então agora o plugin conta com a opção de usar um matriz para definição dos valores, mantendo a opção de array simples e hash, sendo que no primeiro é mantido a ordem na qual os valores são definidos e no caso de hash é retornando em ordem alfabética. Vamos há alguns exemplos para claria as idéias:
Então para a definição de model acima, temos o seguintes resultados na view:
Observe que no caso do so, a ordem não é a mesma estabelecida na chamada do symbolize, mas sim em ordem alfabética do humanize do atribute, enquanto no caso de office os valores vem na ordem que foram declaradas dentro do array.
Bom é isso, em breve mais uma opção de ordenação, mas por hora espero que esta opção agrade a quem precisar.
Novo atributo *_humanize no plugin activerecord_symbolize
Posted on November 14, 2008, under Desenvolvimento, Ruby/Rails, plugins.
O Cássio do /* CODIFICANDO */, fez um post dando uma dica de como simular uma funcionalidade de enum no ActiveRecord, para trabalhar com uma faixa de valores em um dos atributos do model. Então dei uma dica para ele do plugin activerecord_symbolize, do qual eu já falei por aqui e acabei por contribui com algumas alterações.
Trocando idéia com o Cássio, ele sugeri o método *_str, para facilitar na hora de transformar a propriedade do model em um valor legível para o usuário. Bom, eu já tinha feito está alteração localmente e acabei por esquecer o commit/push dela.
A diferença do que ele sugeriu para o que eu tinha feito é que dei o nome de *_humanize para o método, o que é mais Ruby mod do que _str, com o _str poderia ser confundido com o método to_str. Passamos a ter:
Com isso espero atender melhor aos usuário desse plugin, facilitando na hora de obter o valor que sera mostrado na view.
activerecord_symbolize a solução para o seus problemas
Posted on August 19, 2008, under Desenvolvimento, Ruby/Rails.
Um dos erros que cometi quando comecei a desenvolvimento da loja foi usar o tipo enum do banco de dados mysql em algumas tabelas. O erro foi agravado pelo uso do plugin enum-column que adicionar suporte a esse tipo de coluna no ActiveRecord.
O problema se concentra no fato de que o tipo enum não é suportado por todos os bancos de dados, o que impede a migração da aplicação para outro tipos de banco que não sejam mysql. O plugin agrava o problema, não por si só, mas pela falta de atualização.
A partir do Rails 2.0 temos as sexy migration, por isso na criação de uma tabela usamos:
Isso adiciona um coluna do tipo enum no banco de dados, mas atualiza o arquivo schema.rb de forma errada, observe o código abaixo do arquivo schema.rb:
Não existe o método enum para class ActiveRecord::ConnectionAdapters::TableDefinition, o que gera erros quando usamos o schema.rb para criar o banco de dados, o que acontece sempre que rodamos testes por exemplo. A solução para este ultimo problema seria atualizar o plugin, mas ainda sim teríamos o outro problema.
Pensando nisso fui no github atrás de um plugin alternativo, acabei por encontrar o activerecord_symbolize, um plugin que na sua versão básica adiciona o suporte a atribuição de tipos simbólicos as propriedades de um modulo.
Mas lendo a documentação e testando o plugin acabei descobrindo que ele seria pouco para o que queria, por isso fiz um fork do projeto e adicionei algumas características ao plugin. Já fiz um pedido de pull para o projeto original e estou aguardando para ver se minhas modificações são aceitas. Enquanto isso vamos a forma de utiliza-lo.
Para instalar o plugin pode ser fazer o básico:
script/plugin install git://github.com/nuxlli/activerecord_symbolize.git
Na sua tabela usasse tipo string mesmo:
No seu model adicione:
Feito isso, User passa aceitar apenas os valores :female e :male para o atributo gender, gerando um erro de validação caso algum outro valor seja passado, o mesmo acontece com so. Se o symbolize fosse chamado sem a definição de in ele passaria a aceitar qualquer simbolo sem erro de validação.
Um outro recurso que adicionei foi dois helpers para facilitar na hora de criar formulários, ficando assim:
Com isso já se obtém dois campos radios para escolha do gênero e um select para escolha do SO, sendo que suas opções são puxadas diretamente da definição do symbolize.
Para mais informações: activerecord_symbolize
Vamos ajudar na tradução do livro Why’s (Poignant) Guide to Ruby
Posted on June 24, 2008, under Ruby/Rails.
Bom pessoa o Carlos Brando pede neste post por ajuda para terminar a tradução do livro Why’s (Poignant) Guide to Ruby.
Quem souber inglês o suficiente e queira participar veja-la como é fácil fazer. Eu não estou ajudando na tradução porque não domino inglês o suficiente o que pode atrapalhar em vez de ajudar, mas estou aqui fazendo minha parte e pedindo ajuda a quem puder, se assim como eu não pode ajudar na tradução, ajude-nos a pedir ajuda
Passenger versos Thin
Posted on June 9, 2008, under Desenvolvimento, Passenger, Ruby/Rails.
Depois ler sobre o Passenger varias vezes no site do Akita, e utilizar ele na minha maquina para o desenvolvimento da aplicação de e-commerce, resolvi fazer alguns benchmarks e vê como ele se saia comparado ao thin.
Os testes a seguir foram executados com a aplicação em environment production, eles caem consideravelmente quando em development:
No / do site:
Thin (MRI) – Produção: 3.68 [#/sec] (mean)
Thin (Ruby Enterprise): 6.72 [#/sec] (mean)
Passenger (Ruby Enterprise): 2.64 [#/sec] (mean)
Em uma página secundaria de produto:
Thin (MRI): 19.11 [#/sec] (mean)
Thin (Ruby Enterprise): 36.49 [#/sec] (mean)
Passenger (Ruby Enterprise) : 5.53 [#/sec] (mean)
Com esses testes descobri algumas coisas:
- Que minha aplicação esta incrivelmente lenta, 6.77 (o melhor resultado) é inaceitável, preciso melhorar muita coisa para chegar onde preciso.
- O Passenger, pelo menos por hora, só compensa no ambiente de desenvolvimento, pois evita ter que ficar levantando processo para testar as aplicações. obs: isto é para a minha aplicação, para sua pode ser completamente diferente.
- Vou trocar o ruby do servidor de produção pela versão “Enterprise”, os resultados são sem duvida motivadores, a diferença no caso da página de produtos foi gritante.
O resultado não quer dizer absolutamente nada sobre o Passenger, se é ou não mais rápido para todos os casos, isto pode, e vai variar muito de aplicação para aplicação, principalmente no meu caso onde a aplicação ainda não passou por nenhum refatoramento nem um analise profunda de performance.
Além dos testes com a página inicial e com a página de produto, fiz um teste com arquivo estático, uma imagem para ser mais preciso, e deixo um aviso os mais eufóricos, o Passenger, sem a correta configuração pode ser um problema com os arquivos estáticos. A questão esta no fato de que apenas a configuração básica da aplicação no apache faz com que o arquivos estáticos sejam servidos através do ruby o que da um perda de desempenho em responder a esse tipo de arquivo violenta, o certo e fazer como é descrito na tópico 5.3.3 do manual do Passenger.
Pelo menos no meu caso a melhor maneira de servir arquivos estáticos tem sido a configuração do Apache para não passar a requisição das pastas estáticas para os cluster thin. Usando a opção “ProxyPass /images !” o Apache não envia a requisição dos arquivos no caminho /images para o cluster, o que evita processamento dos arquivos pelo ruby.
Meu grande problema agora vai ser refatorar aplicação, fiquei decepcionado em saber que do jeito que esta, estou com uma média de 3.68 [#/sec], isso é muito baixo, e depois do lançamento oficial dos sites pode ser um grande problema
Asset Packger e o problema com pontos
Posted on June 9, 2008, under Desenvolvimento, Ruby/Rails.
Como disse no post anterior estamos trabalhando o jQuery e Asset Packger. So que existe um pequena incompatibilidade entre esses dois.
O Asset Packer tem um pequeno bug que dificulta na hora de trabalhar com arquivos javascript ou css que tenham ponto no nome, como em Jquery-1.2.3.js. O que acontece e que ele usa a função File.extname, que busca pela extensão de um arquivo dado seu nome completo. Então quando você insere no arquivo de configuração do Asset como: jquery-1.2.3, ele interpreta que a extensão desse arquivo já foi digita, e que ela é .3, inserido o arquivo com o nome errado no cabeçalho da página.
Um solução é adicionar o nome completo do arquivo: jquery-1.2.3.js, isso funciona, mas apenas em modo desenvolvimento. O Asset Packger compila todos os arquivos de um grupo em um único arquivo, mas a função que processa os arquivos no helper e no compile são diferentes, sendo que o compile não verifica se já existe um extensão no nome do arquivo, ela apenas julga que é necessário adicionar o .js na hora de incluir os arquivos na compilação.
Para resolver esse problema eu fiz um fork do projeto no Github e corrigi com um pequena modificação.
jQuery e Asset Packager
Posted on June 9, 2008, under Desenvolvimento, Ruby/Rails.
No projeto de e-commerce que estou trabalhando, estávamos com um problema de sobre peso nas páginas, chegando inclusive a 1.4 MB em algumas partes do site.
O principal motivo desse peso todo eram as imagens e banners, como em quase todo site, uma vez resolvido este problema também tivemos problemas com a biblioteca de Javascript: o Prototype. Que o Prototype é gordinho, quase todo mundo já sabe, a questão era como resolver isso. A resposta veio com o jQuery, uma biblioteca Javascript infinitamente superior tanto em recursos como no fato de oferecer versões compactas das bibliotecas que a constitui.
Antes de tentar o jQuery, experimentei usar algumas ferramentas de “compactação” para Javascript, a mais conhecida foi o YUI Compressor, a ferramenta padrão de compressão do projeto Mootools, mas não obtive sucesso, a compactação não funciona com a Prototype, o código final gerado é invalido, e não há muito o que fazer, o problema esta na maneira com que a Prototype foi feita.
Então depois de alguns dias de pesquisa e substituição, consegui achar todos as funcionalidades e bibliotecas equivalentes para o jQuery, uma vez feita a substituição lembrei de plugin que já tinha visto para Rails que podia deixa a coisa ainda melhor.
O Asset Packer é um plugin para auxiliar na utilização de Javascript e Css, com base em um arquivo de configuração pode-se definir pacotes de css ou javascript, da-lhes um nome, e depois incluir esse pacote com apenas um chamada, além disso ele conta com um tarefa rake que permite gerar uma versão compacta dos pacotes.
O grande atrativo do Asset Packer, e que ele inclui o javascript ou css em sua forma descompactada ou compactada de acordo com environment, permitindo ao desenvolvedor trabalhar com os códigos sem compactação durante a fase de desenvolvimento e inserindo as versões compactadas quando em fase de produção. Além destes recursos o Asset Packer ainda trabalha junto ao controle de versão (infelizmente por enquanto apenas com Subversion) e pode ser configurado para gerar as versões compactadas diretamente no servidor, através de configurações junto ao Capistrano.
