Bom, a algum tempo vi uma biblioteca chamada Harmony, para Ruby, que tenta fazer esse processo. Porém, eu achei alguns problemas na biblioteca que meio que me impediam de usá-la do jeito que eu queria, então acabei encontrando uma outra alternativa: The Ruby Racer.

Esta biblioteca usa o interpretador V8, o mesmo usado no Google Chrome, para interpretar Javascript. Possui uma API bem simples, e consegue incorporar objetos Ruby no Javascript de uma forma bem transparente. Como exemplo, digamos que queremos expor uma classe Ruby para o Javascript. Basta usar o código a seguir:

require 'v8'

class UmaClasse
  def initialize(nome)
    @nome = nome
  end

  def imprimir_nome
    puts @nome
  end
end

js = V8::Context.new
js['uma_classe'] = UmaClasse.new
js.eval('uma_classe.imprimir_nome()')

Este código conectará, no Javascript, um objeto chamado uma_classe. Para instalar a biblioteca, um simples “gem install therubyracer” basta, na maioria das vezes. Quando isso não funciona (que nem o meu caso)…

No meu caso, a instalação falhou com a mensagem “ImportError: No module named SCons.Script”. Isto porque, para construir o V8, a gem usa a biblioteca Scons, do Python, e já vem com um Scons imbutido. No meu caso, sabe-se lá porque, isso não funcionou, então para instalar eu basicamente copiei todo o conteúdo do “/usr/lib/ruby/gems/1.8/gems/therubyracer-0.6.3/” para um diretório temporário, então entrei no diretório copiado e editei o arquivo “ext/v8/upstream/Makefile”. Fiz as seguintes alterações:

SCONS=scons
....
$(LIBV8): $(SCONS) $(V8SRC)
        cd build/v8 && GCC_VERSION=$(GCC_VERSION) scons arch=$(ARCH)
...

Estas alterações foram feitas para informar ao V8 que ele deve usar o Scons que está instalado em minha máquina, ao invés do que vem com a Gem. Depois disso, instalei o Scons na minha máquina, e tentei criar novamente a Gem com o comando:

gem build therubyracer.gemspec

Porém, tive o erro:

ERROR:  While executing gem ... (Gem::InvalidSpecificationException)
    ["ext/v8/upstream/2.0.6/benchmarks", "ext/v8/upstream/2.0.6/samples", "ext/v8/upstream/2.0.6/test"] are not files

Então, criei estes arquivos com o comando “touch”

touch ext/v8/upstream/2.0.6/benchmarks
touch ext/v8/upstream/2.0.6/samples
touch ext/v8/upstream/2.0.6/test

E então, tentei novamente com o comando gem. Desta vez, ele criou corretamente a gem, então basta instalá-la com o comando “gem install therubyracer-0.6.3.gem”. Desta vez, tudo correu bem.

Ainda há muito o que fazer com essa gem, porém um projeto que estou tentando aplicar é a criação de uma “emulação DOM” por Ruby. A idéia é criar uma série de classes que contém a informação da DOM (Document, Window, Navigator, etc) e conectá-las via Javascript usando o V8. Dessa forma, daria para fazer testes de aplicações web/rails da seguinte forma, por exemplo:

describe PeopleController do
  it 'should add a new person on the list' do
    get :new_person
    response.should replace_html_of(:people_list)
  end

  it 'should be able to change the color of the list' do
    get :update_page
    response.should change_color_of(:people_list).with("#FF0000")
  end
end

Desta forma, é possível fazer algo bem interessante: “unit-tests” em Javascript. Ou seja, não importa se a “div” está na página ou não – não é necessário as tais “HTML fixtures” que a biblioteca BlueRidge pede – para o teste, basta apenas saber se o código vai ou não substituir o elemento. Detalhes, como se o elemento é uma Div ou é um Parágrafo, não são importantes.

Ainda estou bolando uma maneira de fazer isso. Tentei reimplementar uma parte simples da DOM, porém tenho tido problemas ao carregar a biblioteca Prototype (basicamente, ainda não implementei tudo o que o prototype espera). Tentei conectar o ext.js no V8, sem sucesso (ele espera estar rodando sobre o Rhino). E o Harmony me apresenta alguns problemas esquisitos (código Javascript válido que ele não roda, além de ser bem lentinho para usar em Specs). Ainda nem sequer criei um projeto no Github, mas quando eu criar, publicarei aqui.


2 Comments

Charles Lowell · 2010-05-19 at 16:12

I don’t understand Portuguese, but it looks like you were having some problems with the build.

If possible, I’d like to find out what happened so that I can fix it for everybody else. Hope you enjoy it!

cheers,
Charles

Testando Javascript no Rails | Maurício Szabo · 2011-09-21 at 10:57

[…] vem como uma Ruby String, ou um Numeric, enfim). Já falei sobre isso quando estudei “The Ruby Racer” e os testes com V8 no Ruby, até me interessei pelo “env.js”, porém na época a […]

Comments are closed.