MouseOver Studio

MouseOver Studio header image 1

Acessando variáveis nos filtros Liquid

por Diego Carrion - May 26th, 2009 · 1 comentário

Se por acaso precisarem acessar alguma variável a partir de um filtro do Liquid podem utilizar a variável de instancia context.

Tal comportamento pode ser desejado ao querer implementar algo similar ao asset_url do Shopify:

module SitesFilter
  def asset_url(input)
    "/system/assets/#{@context['company'].id}/#{input}"
  end
end

Liquid::Template.register_filter(SitesFilter)

→ 1 comentárioTags: Markup · Template · liquid · rails · ruby

Corrigindo um problema de corrupção no Git

por Diego Carrion - May 21st, 2009 · 2 comentários

As vezes, quando se meche com submódulos do Git da forma errada se termina aparentemente corrompendo o repositório e recebendo o seguinte erro ao tentar realizar um pull:

error: git-upload-pack: git-pack-objects died with error.
fatal: git-upload-pack: aborting due to possible repository corruption on the remote side.
remote: Generating pack…
remote: Done counting 39 objects.
remote: Result has 28 objects.
remote: error: unable to find b490fa1a6d81e39d3a8d99f9cce8b57c3397b7d7
remote: fatal: unable toremote: aborting due to possible repository corruption on the remote side.
fatal: protocol error: bad pack header

Não sei se seja o melhor ou único jeito de contornar o problema mas uma solução que encontrei foi dar um pull na URL pública e depois dar um push.

→ 2 comentáriosTags: Git

Controlando o servidor de Rails dentro dos testes do Selenium

por Diego Carrion - May 20th, 2009 · Sem comentários

Para não esquecer disso uma segunda vez aqui vá:

Se estiverem trabalhando com Rails e Selenium e desejam subir e derrubar o servidor automaticamente antes e despois dos testes então podem utilizar o Mongrel:

mongrel_rails start -e test -d
mongrel_rails stop

Por exemplo, eu que estou utilizando Selenium com Cucumber, tenho meu env.rb assim:

require 'spec/expectations'
require 'selenium'

# "before all"
`mongrel_rails start -e test -d`
`rake db:populate RAILS_ENV=test`
browser = Selenium::SeleniumDriver.new("localhost", 4444, "*chrome", "http://localhost", 15000)

Before do
  @browser = browser
  @browser.start
end

After do
  @browser.stop
end

# "after all"
at_exit do
  browser.close rescue nil
  `mongrel_rails stop`
end

→ Sem comentáriosTags: bdd · cucumber · mongrel · rails · selenium

Testando Authlogic com RSpec, the Remarkable way

por Diego Carrion - May 14th, 2009 · 4 comentários

Davis Cabral criou um plugin para o Remarkable para poder testar facilmente o Authlogic chamado de authlogic_plugin. Com ele podemos escrever código como o seguinte:

describe User do
  should_be_authentic
end

Conversando com o Davis ele me comentou que demorou quatro minutos em criar o plugin, utilizando como base o Remarkable::Paperclip, deve ser muito fácil né?

Se você gostou do plugin, considera recomendar o Davis no Working With Rails, ai você aproveita e me recomenda também :)

→ 4 comentáriosTags: Authlogic · Remarkable · bdd · rails · rspec

Plugins de Remarkable para ActsAsTaggableOn, Paperclip e ThinkingSphinx

por Diego Carrion - May 9th, 2009 · Sem comentários

Trabalhado num projeto me vi na necessidade de criar três plugins para o Remarkable: Remarkable::ActsAsTaggableOn, Remarkable::Paperclip e Remarkable::ThinkingSpinx.

Basicamente permitem escrever código como o seguinte:

describe User do
  should_act_as_taggable_on :categories

  should_have_attached_file :logo

  should_index 'addresses.city', :as => :address
  should_have_index_attribute :priority
end

Se esses plugins ajudaram você, considera por favor também me ajudar me recomendando no Working With Rails.

→ Sem comentáriosTags: ActsAsTaggableOn · Paperclip · RSpec::Rails · Remarkable · ThinkingSphinx · Uncategorized · plugin · rails · rspec

Não deixa o mar te engolir

por Diego Carrion - April 8th, 2009 · 20 comentários

Na semana passada fui contactado para adicionar funcionalidades no sistema feito em Rails de um banco que todos conhecem. No primeiro momento fiquei contente e surpreso de um banco ter realizado um projeto utilizando Rails como tecnologia, já trabalhei com sistemas para diversos bancos e o mais moderno que vi foi o Struts 2.

Os sentimentos foram mudando conforme ia revisando o código que já estava feito. Sem exagerar, essa aplicação feita em Rails é a pior aplicação que eu já vi, considerando também aplicações feitas em Java, PHP e ate ASP, tecnologias com as quais já trabalhei.

Muitos devem estar se perguntando agora como uma aplicação feita em Rails pode ser tão assustadora assim, por isso vou mencionar umas “características” dela.

Para começar, a aplicação não utilizava um sistema de controle de versões, os arquivos estavam por exemplo assim: index.html.erb, index.html.erb.1, index.html.erb.14112008, e por ai vai.

O primeiro código que analisei foi o do modelo, abri uns arquivos e encontrei todo tipo de coisas. Existia HTML e XML que estava sendo gerado no modelo, existiam métodos que recebiam como parâmetros o nome do controller e o nome da action, alguns ate o nome da view. Alguns métodos eram nomeados the ruby way e outros camelCase, e para finalizar aqui, encontrei métodos com as mesmas linhas de implementação, mas com nome diferente.

Seguidamente passei aos controllers, o código não melhorou. Tinham controllers com mais de 1000 linhas de código, métodos com mais de 100 linhas, menus e outras coisas dinâmicas em HTML sendo geradas e novamente, variáveis de tudo tipo, the ruby way e camel case.

Para finalizar: as views. Aqui não tenho muito a dizer, quase tudo era HTML puro, muito HTML, muita coisa repetida. Tinha muito HTML porque não eram utilizados os layouts do Rails, no máximo eram utilizados alguns partials, que foram colocados na pasta layout…

Mas por que estou dizendo todo isto? Porque não podemos ver coisas assim e ficar de braços cruzados!

Eu venho do mundo Java e no mundo Java tem uma excelente tecnologia chamada Hibernate. Mesmo sendo excelente, ela nunca ganhou seu espaço firme no mercado brasileiro justamente porque sempre alguem a utilizou do jeito errado. São varias empresas já as que me dizerem: “Não utilizamos mais Hibernate porque em tal projeto não deu certo”.

A mesma historia não pode se repetir com Rails!

Eu tenho enviado um email para a empresa responsável pelo sistema dando a conhecer que o produto deles foi realizado com uma qualidade péssima e dei a conhecer que não existia necessidade disso, dado que eu sei que no mercado existem excelentes desenvolvedores que morrem de vontade de trabalhar com Rails e não possuem a oportunidade. Muitas pessoas se esforçam fortemente para melhorar o desenvolvimento de software, especialmente no Brasil, e um trabalho desses simplesmente pode causar um estrago enorme .

No mesmo email prometi também que não ia mencionar o nome da empresa se ela me prometesse que ia melhorar essa qualidade.

Meu email não foi respondido, mas por outra pessoa eu ja sei que foi lido. A mesma pessoa comentou que não era meu problema, que a empresa não se importava com a qualidade do projeto, que ela tinha conseguido vender ele é ter ganhado dois prêmios, que isso era o que importava para ela, finalizando com que ia ser processado e iam queimar meu nome se anunciava o nome da consultora.

Não sei por que poderia ser processado se não tenho mentido em nada, mas para não arriscar, vou manter o nome em off.

Sobre o nome, eu queria deixar claro que estou escrevendo esse texto porque não consigo me conformar com coisas feitas de mal jeito. Eu amo minha profissão e meu pais e essas duas coisas são minhas principais motivações para realizar as coisas com a maior qualidade possível, isso é o que podem esperar de mim.

Acho que não é preciso argumentar e que tudo mundo consegue entender aqui que empresas com esse pensamento, que não aspiram a excelência e não se preocupam com qualidade são negativas para os que se esforçam com melhorar a comunidade e a industria de Software.

Queria dar a conhecer a vocês que esse tipo de entidades já chegaram ao mundo Rails e incentivar a que, no possível, tentem evitar que aconteçam essas coisas que vocês acham erradas e que indiretamente terminam afetando a todos nos.

→ 20 comentáriosTags: comunidade · rails

RSpec::VRaptor agora com novos matchers e compatível com VRaptor Nice URLs

por Diego Carrion - March 30th, 2009 · 1 comentário

Ja passaram uns dias desde que anuncie no meu Twitter a noticia, mas somente agora peguei um tempo para escrever aqui no blog então aí vai:

o RSpec::VRaptor é totalmente compatível com o novo VRaptor 2.6 Nice URLs!

O VRaptor 2.6 vem com um plugin chamado Nice URLs que permite definir rotas para à aplicação num arquivo, estilo Rails.

Mas não só isso, a ultima versão do RSpec::VRaptor adicionou uns matchers muito legais, segue um exemplo do que é possível realizar agora:

describe CarController do

  context "na action action1" do

    before :all do
      get "/car/action1", :cookies => {'key' => 'value'}
    end

    it "deve ter um header com a data da resposta" do
      @response.headers['Date'].should_not be_nil
    end

    it "não deve ter uma view de resposta" do
      @request.should be_viewless
    end

  end

  context "na action action2" do

    it "deve renderizar o arquivo action2.erb" do
      get "/car/action2"
      @request.should render("car/action2.erb")
    end

    it "deve redirecionar para a home se o usuário estiver logado" do
      get "/car/action2", :session => {'logged' => true}
      @response.should redirect_to("user/home")
    end

  end

end

Como podem ver, agora não só podemos injetar cookies no nossos requests, também podemos verificar os headers de resposta, validar se a requisição é viewless (método com anotação @Viewless), se vai ser renderizado um arquivo x ou se a resposta redireciona para algum outro recurso.

→ 1 comentárioTags: bdd · rspec · tdd · vraptor

Ruby vs Java e como a tartaruga venceu novamente a lebre

por Diego Carrion - March 8th, 2009 · 15 comentários

Trabalhei dois sprints de duas semanas num projeto programado em Java, junto a dois desenvolvedores mais. Antes de começar os sprints sugeri utilizar a arquitetura Ruby on Rails mas o cliente alegou que a performance era um fator importantíssimo.

A escolha das ferramentas Java foi livre pelo que felizmente conseguimos pegar o que tem de melhor no mercado: VRaptor e Hibernate. Essas duas ferramentas nos ajudaram a acelerar bastante o tempo de desenvolvimento. Não esquecer que o projeto foi feito em 4 semanas, por tres desenvolvedores (guardar esses valores para mais tarde).

Somente como momento propaganda, a versão utilizada do VRaptor foi a VRaptor Sexy URLS.

Uma vez terminado o ultimo sprint, dediquei um tempo à realizar uns testes de stress enquanto analisava tudo com o JProfiler. A aplicação não possuía nenhum memory leak ou coisa similar, mas mesmo assim algumas alterações melhoraram a performance.

Foi realizado um novo deploy da aplicação no ambiente de produção e o cliente gostou do produto, pelo que foi mantido assim.

Uma semana depois aproveitei um tempo livre que teve para desenvolver a aplicação novamente, dessa vez utilizando Rails. Lembram quanto tempo demoro utilizando os frameworks Java? Utilizando Rails + plugins consegui desenvolver a mesma aplicação em somente duas horas!

Mas isso não é tudo, queria comparar a performance da aplicação feita em Rails com a feita em Java. Eu tinha um script que simulava diversos usuários utilizando a aplicação, o mesmo script que utilizei para realizar o profiling da aplicação Java, pelo que aproveitei ele para medir o tempo de execução frente as duas aplicações, uma rodando sobre o Glassfish e a outra sobre o Passenger.

Para surpresa de muitos, a aplicação Rails rodando sobre Passenger respondeu bem mais rápido às diferentes requisições que a aplicação Java (32 vs 60 segundos)! Isso pode surpreender a muitos, mas não é a primeira vez que algo assim acontece. No Falando em Java 2008 o Fabio Kung mencionou que parte do Guj foi rescrito em Rails, ao mesmo tempo que a performance melhorou notavelmente. Mas sem lugar a dúvida, o exemplo maior de uma aplicação Java que foi rescrita em Rails sem perder a performance é o caso do YellowPages.com, aplicação com nada menos que 150 mil requisições por segundo. Mas detalhes sobre a rescrita podem ser vistos aqui.

Para ir terminando a historia, eu consegui gastar um bom tempo tunando a JVM e o servidor Glassfish, mas somente por diversão, como desafio, porque para o cliente não mudou nada! Não mudou nada porque a diferença somente pode ser percebida com MUITOS usuários, realizando MUITAS requisições, bem mais, mas bem mais mesmo das que a aplicação pretendia receber.

Se você é uma das pessoas responsáveis por escolher uma tecnologia num projeto e você pretende deixar de escolher Rails porque alega alguma coisa relacionada a performance, então você deve pensar no assunto uma vez mais.

Caso você seja uma rara exceção, vamos ser sinceros, tua aplicação bem desenvolvida nunca vai precisar da JVM e do servidor tunados ao máximo, nem sequer tunados ao ponto no qual uma aplicação em Rails não consiga chegar. Isso considerando que a aplicação vai estar bem desenvolvida, mas provavelmente ela não vai estar. Na maioria dos casos as aplicações Java tem problemas de performance a nível de código. Os desenvolvedores escrevem tanto mas tanto código que terminam deixando brechas para poder acontecer um processamento elevado ou ate alguns memory leaks.

Quanto menos código você escrever e quanto mais simples ele for, menores vão ser as possibilidades de um problema acontecer, e isso é algo que ajuda as aplicações feitas em Rails a terem uma boa performance com esforço mínimo, as chances de errar são muito menores.

→ 15 comentáriosTags: java · performance · ruby

Demorou mas chegou: VRaptor Sexy URLs e RSpec::VRaptor

por Diego Carrion - January 27th, 2009 · 3 comentários

A galera que me segue no Twitter já está sabendo da noticia mas para os que não, aqui vá:

VRaptor Sexy URLs

Estou publicando oficialmente o VRaptor Sexy URLs. O VRaptor Sexy URLs é um fork da versão oficial do VRaptor 2 que ao contrario de trabalhar sobre uma servlet, trabalha sobre um filtro, pelo que junto à outras configurações permite que chamemos nossas actions no estilo:

http://my.host.com/controller/action

Anteriormente tínhamos que chamar nossas actions de um jeito que, após trabalhar com Rails, nunca mais considerei tão legal:

http://my.host.com/controller.action.logic

Eu me comuniquei com o Fabio Kung para tentar colocar minhas alterações no repositório oficial mas eles já estão trabalhando na mesma solução, implementada de outro jeito. Parece que na próxima versão do VRaptor essas implementações já estarão disponiveis, ate lá podem ir utilizando o fork que se encontra no GitHub.

RSpec::VRaptor

O RSpec::VRaptor é talvez a melhor coisa que pode ser aproveitada ao utilizar o VRaptor Sexy URLs. O RSpec::VRaptor foi inspirado no RSpec::Rails e funciona de forma muito similar.

Para os que não conhecem o RSpec::Rails, ele é um plugin para
o Rails que permite, entre outras coisas, testar os controllers dele sem ter que se preocupar por criar um monte de mocks que simulem o stack do Rails. Legal ne? O RSpec::VRaptor faz o mesmo com o VRaptor Sexy URLs.

Em poucas palavras, você pode testar seu controllers assim:

describe UserController do

  context "no serviço xpto" do

    before :all do
      get "/user/xpto", :request => {'param1' => 'value1'},
                        :session => {'login' => 'dcrec1'},
                        :inject => {'user' => User.new},
                        :headers => {'Host' => '20.85.17.10'}
    end

    it "deve enviar à view um atributo 'logado' como true" do
      @request.attributes['logado'].should be_true
    end

    it "deve retornar como código de resposta 203" do
      @response.status.should eql(203)
    end

    it "deve salvar na sessão o valor do param1" do
      @session.attributes['param1'].should eql('value')
    end

  end

end

Acredito que não exista nenhuma solução na linguagem Java que permita criar testes funcionais tão elegantes. Se você é um programador Java e ainda não desenvolve em Ruby, essa aqui é uma excelente demostração de por que você deveria começar a aprender a linguagem. Pode ser que você não chegue a utilizar o VRaptor Sexy URLs, mas você poderia criar algo similar para teu framework de preferencia.

Se nos dirigirmos à documentação do VRaptor, na parte de testes, poderemos ver que eles sugerem testar os controllers instanciando eles e setando os parâmetros. Isso se deve a que as anotações não são interpretadas pelo que temos que realizar as injeções manualmente. Devemos modificar nosso código para que possa ser testável ate um certo ponto, dado que como as anotações não participam, não sabemos se colocamos elas certas ou se temos esquecido de alguma.

Com RSpec::VRaptor não temos esse problema, devido a que as anotações e as rotas são interpretadas normalmente, como se a requisição tivesse vindo via http! Podemos também utilizar os parâmetros opcionais :request, :inject, :session e :headers para definir os parâmetros do request, injetar objetos no controller, modificar a sessão http e também alguns headers, respetivamente.

Além de tudo isso também ganhamos as features do excelente RSpec, como os mocks, expectativas e a possibilidade de imprimir a saída dos testes em diversos formatos e poder integrar ele com ferramentas muito boas como o autotest-notification ou ate o Cucumber!

Tudo isto é possível por causa do JRuby, excelente tecnologia que nos permite integrar as linguagens Ruby e Java. De novo, se você programa em Java e ainda não aprendeu Ruby, não perda mais tempo. Aprendendo Ruby você vai ser tornar também um melhor programador Java, vai poder utilizar o RSpec::VRaptor é também as novas surpresas que estão por vir.

→ 3 comentáriosTags: java · jruby · rspec · ruby · vraptor

Implementando interfaces Java com JRuby (+ Bonus)

por Diego Carrion - January 12th, 2009 · Sem comentários

Caso estejam trabalhando com JRuby e queiram implementar uma interface Java podem fazê-lo com a instrução include:

class MockedHttpSession
  include javax.servlet.http.HttpSession
  ...
end

Bonus

Caso estejam estendendo uma classe Java com JRuby e desejem chamar no construtor um dos métodos já implementados pela classe pai deverão utilizar antes a instrução super:

class MockedUser < User
  def initialize(password)
    super
    setPassword password
  end
  ...
end

Caso não chamem a instrução super irão receber a seguinte mensagem de erro:

invokee not a java object

Ultimamente estou mexendo bastante com JRuby. Se for do teu interesse, pode me seguir no Twitter para se manter ao tanto.

→ Sem comentáriosTags: java · jruby