Вы находитесь на странице: 1из 6

SEO JAVA: NESTA SEO VOC ENCONTRA ARTIGOS INTERMEDIRIOS E AVANADOS SOBRE JAVA

&YQMPSBOEPP+3VCZ
5SB[FOEPP3VCZQBSBEFOUSPEP+BWB
esse artigo exploraremos como
utilizar o JRuby para que voc
possa usufruir de todo o poder
da linguagem Ruby sem ter que abandonar
a plataforma Java. Veremos como instalar
e configurar o JRuby corretamente para
executar de maneira fcil qualquer cdigo Ruby dentro da mquina virtual Java.
Veremos tambm como fazer chamadas
de Java para Ruby e vice-versa.
Uma vez entendido o JRuby, daremos
uma olhada no famoso framework de
persistncia do Ruby, o ActiveRecord, e
veremos como algumas mgicas de metaprogramao do Ruby podem tornar um
framework mais gil e intuitivo.

3FTVNP%FW.BO

O Que o JRuby?

a sua forte expressividade. Sabendo utilizar o JRuby voc ter ao seu dispor uma importante ferramenta

O JRuby uma implementao opensource em Java da linguagem Ruby. Isso


significa que em teoria qualquer cdigo
Ruby pode ser executado dentro da mquina virtual Java. O JRuby entretanto vai
alm disso, permitindo um mix de Java
com Ruby, ou seja, possvel usar objetos
Ruby dentro de cdigo Java e objetos Java
dentro de cdigo Ruby. Com o aumento
da popularidade do framework web Ruby
on Rails, ficou claro que algumas tcnicas
da linguagem Ruby seriam muito difceis
de serem reproduzidas pela linguagem
Java. Foi nesse ambiente que surgiu o
projeto JRuby, que com a posterior contratao dos principais desenvolvedores
pela Sun, sinalizou para o mercado que
as vantagens desta linguagem dinmica
no poderiam ser negligenciadas pela
plataforma Java.

para programar a sua lgica de uma maneira clara e eficiente, sem ter que abandonar a j madura plata-

Java versus Ruby


Analisar a linguagem Ruby com todas as
suas particularidades est fora do escopo
desse artigo. Mas antes de comearmos
vamos fazer um rpido comparativo entre

De que se trata o artigo:


Nesse artigo exploraremos como utilizar o JRuby para que voc possa usufruir de todo o poder da
linguagem Ruby sem ter que abandonar a plataforma Java. Veremos como instalar e configurar o JRuby
corretamente para executar de maneira fcil qualquer cdigo Ruby dentro da mquina virtual Java.
Veremos tambm como fazer chamadas de Java para Ruby e vice-versa.
Uma vez entendido o JRuby, daremos uma olhada no famoso framework de persistncia do Ruby, o
ActiveRecord, e veremos como algumas mgicas de metaprogramao do Ruby podem tornar um
framework mais gil e intuitivo.

Para que serve:


Fornecer um meio de utilizar os conceitos avanados da linguagem Ruby como metaprogramao,
closures, etc. sem ter que abandonar a plataforma Java, obtendo assim o melhor dos dois mundos.

Em que situao o tema til:


Linguagens dinmicas esto em moda e so excelentes para descrever um algoritmo complexo devido

forma Java.

Explorando o JRuby:
O JRuby permite utilizar todos os recursos da linguagem Ruby dentro da plataforma Java. Por exemplo,
possvel utilizar closures e metaprogramao, duas funcionalidades bastante interessantes da linguagem
Ruby e que no so suportadas pela linguagem Java. Executar cdigo Ruby a partir de cdigo em Java e
vice-versa fica fcil com o JRuby. Com a maturidade do JRuby, a tendncia termos os programadores Java
utilizando o Ruby dentro da mquina virtual ao invs de partirem para solues 100% Ruby.

Ruby e Java. Podemos afirmar


que Java uma linguagem de
programao esttica, compilada
e orientada a objetos, enquanto
Ruby uma linguagem dinmica, interpretada e orientada
a objetos.
Em Java uma varivel precisa
ser declarada com um tipo, e
uma vez declarada o seu tipo
no pode mais ser alterado.
Por isso que se diz que Java
uma linguagem de tipagem
esttica, enquanto Ruby
uma linguagem de tipagem

32 Java Magazine t Edio 68


Java 68_copia.indb 32

17/04/2009 15:30:08

&OUFOEBDPNPGVODJPOBP
+3VCZFVUJMJ[FUPEPPQPEFS
EBMJOHVBHFN3VCZEFOUSPEB
QMBUBGPSNB+BWB

SERGIO OLIVEIRA JUNIOR


dinmica. Em Ruby, assim como em
JavaScript, Perl e Python, uma varivel
pode armazenar diversos tipos de objetos diferentes ao longo de sua vida. O
cdigo abaixo apresenta um exemplo
dessa caracterstica do Ruby em relao
ao Java.
// Java
String s = Java;
s = 1; // Erro de compilao
# Ruby
s = Ruby
s = 1 # Ok

Aqui cabe a observao de que ser dinmica, e consequentemente mais flexvel,


no necessariamente melhor que ser
uma linguagem esttica. Essa sempre
uma questo relativa aplicao. O fato de
Java ser uma linguagem esttica permite
que o compilador detecte diversos erros, o
que pode garantir uma maior robustez. Se
um mtodo precisa receber uma varivel
do tipo Integer e devido a um erro de programao ele recebe uma varivel do tipo
Float, em Java esse erro ser mostrado pelo
compilador e se voc estiver utilizando
uma IDE moderna provavelmente ficar
sabendo do seu erro no mesmo instante
em que o digitar. Em Ruby esse erro ser
detectado apenas quando o sistema for
executado, seja no ambiente de testes ou
em produo.
No entanto, IDEs com editores cada vez mais
inteligentes, por exemplo o NetBeans 6.5, comeam
a oferecer recursos como completamento automtico
e validao esttica para Ruby.

Outra diferena importante entre Java


e Ruby que em Ruby no h tipos primitivos, isto , toda e qualquer varivel
e valor em Ruby necessariamente um
objeto. comum encontrar amantes de

Listagem 1. Objetos em Ruby.


# Tudo em Ruby um objeto:
1.class
# Fixnum
3.14.class
# Float
0.class
# Fixnum
false.class
# FalseClass
true.class
# TrueClass
nil.class
# NilClass (Equivalente ao null de Java)

Listagem 2. Closures em Ruby.


a = [1,2,3]
a.each { |x| puts x }
# ou
my_block = lambda { |x| puts x }
a.each(&my_block) # my_block um objeto do tipo Proc

Ruby afirmando com orgulho que Ruby


uma linguagem 100% orientada a objetos
(OO-pura). Apesar dessa afirmao ser
totalmente verdadeira, as suas vantagens
tambm so relativas aplicao em
questo. Variveis primitivas no so
armazenadas na memria heap como os
objetos, no so coletadas pelo coletor de
lixo (Gargage Collector), no possuem
referncias, so menores e podem ser
armazenadas diretamente no stack e at
mesmo nos registradores da CPU. Java
suporta tipos primitivos por uma questo
de performance, enquanto Ruby aboliu
as variveis primitivas por uma questo
de consistncia e simplicidade. Veja na
Listagem 1 alguns exemplos de objetos
em Ruby.
Para finalizar nossa rpida comparao
entre Java e Ruby, no poderamos deixar
de mencionar o suporte a closures de Ruby
e a Metaprogramao. Closures so blocos
de cdigo que podem ser criados e passados
de um lado para o outro do seu programa
como objetos (de fato, closures so objetos,
integrando o cdigo ao modelo OO-puro).
bastante comum em Ruby que mtodos
recebam como parmetro um bloco de cdi-

go. No exemplo da Listagem 2 o mtodo each


recebe um bloco de cdigo. Tudo que o mtodo each precisa fazer executar este bloco de
cdigo recebido para cada um dos elementos
do seu objeto, nesse caso um array.
O recurso de closures foi proposto para a verso 7
do Java (Dolphin); ver Closures em Java, Edio 62.
Infelizmente, a proposta no emplacou e os programadores Java tero que esperar pelo Java 8, 9... ou se
no tiverem pacincia, uma linguagem alternativa
como Ruby (JRuby), Groovy, JavaFX, Scala, Python
(Jython), JavaScript (Rhino), etc.

O tema Metaprogramao bastante


vasto e complexo, ento me limitarei em
definir o termo como a capacidade de
criar programas que se auto-modificam,
ou seja, cdigo que serve para criar cdigo
de programao em tempo de execuo.
Iremos voltar ao assunto mais adiante,
mas por enquanto voc pode ficar com
o exemplo da Listagem 3, que cria um
mtodo em tempo de execuo.

Instalando o JRuby
Instalar o JRuby muito fcil. Siga os
passos abaixo:

Edio 68 tJava Magazine


Java 68_copia.indb 33

33

17/04/2009 15:30:09

&YQMPSBOEPP+3VCZ

Listagem 3. Metaprogramao em Ruby


class Foo
def add_method(name)
eval(def #{name}; puts Wow!; end)
end
end
f = Foo.new
f.add_method(sayWow)
f.sayWow
# mtodo criado em tempo de execuo

Listagem 4. Executando o JRuby.


c:\>jruby -v
jruby 1.1.6 (ruby 1.8.6 patchlevel 114) (2008-12-17 rev 8388) [x86-java]
c:\>jruby -S gem -v
1.3.1
c:\>jruby -S gem list --local
*** LOCAL GEMS ***
rake (0.8.3)
rspec (1.1.11)
rubyforge (1.0.1)
sources (0.0.1)
c:\>jirb
irb(main):001:0> puts Hello JRuby
Hello JRuby
=> nil

Listagem 5. Instalando Gems


c:\>jruby -S gem install activerecord
Successfully installed activesupport-2.2.2
Successfully installed activerecord-2.2.2
2 gems installed
Installing ri documentation for activesupport-2.2.2...
Installing ri documentation for activerecord-2.2.2...
Installing RDoc documentation for activesupport-2.2.2...
Installing RDoc documentation for activerecord-2.2.2...
c:\>jruby -S gem install activerecord-jdbcmysql-adapter
Successfully installed activerecord-jdbc-adapter-0.9
Successfully installed jdbc-mysql-5.0.4
Successfully installed activerecord-jdbcmysql-adapter-0.9
3 gems installed
Installing ri documentation for activerecord-jdbc-adapter-0.9...
Installing ri documentation for jdbc-mysql-5.0.4...
Installing ri documentation for activerecord-jdbcmysql-adapter-0.9...
Installing RDoc documentation for activerecord-jdbc-adapter-0.9...
Installing RDoc documentation for jdbc-mysql-5.0.4...
Installing RDoc documentation for activerecord-jdbcmysql-adapter-0.9...

Listagem 6. Chamando Java do Ruby


c:\>jirb
irb(main):001:0> s = Java::JavaLang::String.new(Eu sou uma String do Java)
=> #<Java::JavaLang::String:0x48bc64 @java_object=Eu sou uma String do Java>
irb(main):002:0> puts s
Eu sou uma String do Java
=> nil
irb(main):003:0> puts s.toUpperCase
EU SOU UMA STRING DO JAVA
=> nil
irb(main):004:0> puts s.to_upper_case
EU SOU UMA STRING DO JAVA
=> nil
irb(main):006:0> puts s.getBytes
[B@19cd5f5
=> nil
irb(main):005:0> puts s.bytes
[B@704cf5
=> nil

Baixe o arquivo ZIP com a instalao da


ltima verso do JRuby no endereo dist.codehaus.org/jruby/ (Ex: jruby-bin-1.1.6.zip);

no seu diretrio raiz ou em qualquer outro
diretrio. interessante criar um diretrio
C:\jruby e extrair o contedo do zip dentro
dele, de forma que no futuro voc possa
colocar as novas verses do JRuby dentro
de um mesmo diretrio;
 
HOME para o diretrio raiz do JRuby;
 
OPTS para -rubygems, assim voc no precisa requerer rubygems nos seus cdigos.
 
 

bin no seu PATH de forma que voc possa
executar o comando jruby de dentro de
qualquer diretrio.
Aps executar os passos acima, voc ter
o jruby disponvel no seu shell e poder
execut-lo de qualquer diretrio. Veja a
Listagem 4 com alguns exemplos.

Instalando Gems
Uma das funcionalidades mais interessantes do Ruby a possibilidade de facilmente
baixar e instalar novos frameworks para
a linguagem. Esses frameworks no vocabulrio do Ruby so chamados de Gems
(pedras preciosas) e so gerenciados atravs
da extenso RubyGems, j includa na instalao padro do JRuby. Vamos comear
instalando alguns gems que utilizaremos
posteriormente nesse artigo. Para isso, voc
precisar estar conectado Internet para executar os comandos mostrados na Listagem
5 e instalar o gem ActiveRecord.
Repare que caso o gem que voc esteja instalando
dependa de outros gems, o RubyGems automaticamente baixa e instala todas as dependncias.

Chamando cdigo Java a partir do Ruby


O JRuby permite que objetos Java sejam
instanciados e utilizados de dentro de
cdigo Ruby. Para evitar o conflito entre
objetos Java e objetos Ruby que possuem
o mesmo nome, como por exemplo, String,
File, Date etc., o JRuby automaticamente or-

34 Java Magazine t Edio 68


Java 68_copia.indb 34

17/04/2009 15:30:09

ganiza os pacotes da linguagem Java dentro do mdulo Java, obedecendo seguinte


conveno: java.utilJava::JavaUtil, java.io
Java::JavaIo e java.langJava::JavaLang.
Ento, para instanciar uma String do Java
(e no do Ruby) dentro do seu cdigo Ruby,
voc pode fazer: s = Java::JavaLang::String.
new(Eu sou uma String do Java). Voc tambm
pode importar qualquer classe ou jar externos atravs dos mtodos import (ex: import
jm.jruby.User), include_class (ex: include_class
jm.jruby.User) e require (ex: require jm/jruby/
mylib.jar).
Vamos iniciar uma seo do jirb para
estudar alguns exemplos. O jirb o Jruby
em modo interativo, de forma que voc
pode executar cdigo diretamente no
console. Veja na Listagem 6 o exemplo de
uma sesso do jirb.
Algumas observaes importantes que
voc j deve ter notado: O JRuby automaticamente fornece os mtodos de um objeto
Java com a nomenclatura padro do Ruby;
ex: toUpperCase()to_upper_case. Ele tambm
fornece os mtodos do padro JavaBeans
no padro Ruby, ex: s.getBytes() s.bytes.
O mesmo se aplica para setters (ex: obj.
setNome(Sergio)obj.nome = Sergio) e para
getters booleanos (ex: obj.isDiretor()obj.diretor?). Isso torna a utilizao de objetos Java
dentro de cdigo Ruby mais compatvel
com as convenes da linguagem Ruby.
O JRuby tambm tenta converter sempre que possvel objetos Ruby para os
seus equivalentes em Java. Por exemplo,
se um mtodo Java recebe um java.lang.
String como parmetro, voc pode passar
para o mtodo uma string do Ruby que a
converso acontece automaticamente. O
mesmo acontece para um array de Ruby
que pode ser convertido para um java.util.
List. E como voc j deve suspeitar, Ruby
hashes so automaticamente convertidos
para java.util.Map.
Entretanto, e estranhamente, o JRuby no
converte automaticamente Ruby arrays
para arrays primitivos do Java, logo, se
um mtodo Java espera receber um String[]
e voc quer passar um array de strings do
Ruby, voc precisa antes, explicitamente,
convert-lo usando o mtodo to_java. Outro
inconveniente - efeito da tipagem dinmica do Ruby que o mtodo to_java por

Listagem 7. Chamando Ruby do Java (JRubyInterpreter.java)


import java.util.*;
import java.io.*;
import
import
import
import

org.jruby.Ruby;
org.jruby.RubyObject;
org.jruby.RubyRuntimeAdapter;
org.jruby.javasupport.JavaEmbedUtils;

public class JRubyInterpreter {


private Ruby runtime;
private RubyRuntimeAdapter evaler;
public JRubyInterpreter() throws IOException {
// diretrios onde o JRuby vai procurar arquivos Ruby (ex: require user.rb)
List<String> loadPaths = new ArrayList<String>();
loadPaths.add(.);

runtime = JavaEmbedUtils.initialize(loadPaths);
evaler = JavaEmbedUtils.newRuntimeAdapter();

// avaliar/executar qualquer cdigo Ruby passado como uma String...


public RubyObject eval(String code) {
return (RubyObject) evaler.eval(runtime, code);
}
// chamar um mtodo de um objeto ruby... (com parametros e tipo de retorno)
public Object call(Object rubyObject, String methodName, Class<? extends
Object> returnType, Object ... params) {
return JavaEmbedUtils.invokeMethod(runtime, rubyObject, methodName, params,
returnType);
}
// chamar um mtodo de um objeto ruby... (sem parametros ou tipo de retorno)
public Object call(Object rubyObject, String methodName) {
return JavaEmbedUtils.invokeMethod(runtime, rubyObject, methodName, new
Object[0], Object.class);
}
// chamar um mtodo de um objeto ruby... (sem parametros e com tipo de retorno)
public Object call(Object rubyObject, String methodName, Class<? extends
Object> returnType) {
return JavaEmbedUtils.invokeMethod(runtime, rubyObject, methodName, new
Object[0], returnType);
}
// chamar um mtodo de um objeto ruby... (com parametros e sem tipo de retorno)
public Object call(Object rubyObject, String methodName, Object ... params)
{
return JavaEmbedUtils.invokeMethod(runtime, rubyObject, methodName, params,
Object.class);
}
// carregar um arquivo ruby qualquer do loadpath...
public void require(String file) {
eval(require + file + );
}
public static void main(String[] args) throws IOException {
JRubyInterpreter ruby = new JRubyInterpreter();
RubyObject array = ruby.eval(Array.new); // criar um Array de Ruby
for(int i=0;i<10;i++) {
ruby.call(array, push, i); // chamar o mtodo push de Array
}
System.out.println(ruby.call(array, to_s, String.class)); // chamar o mtodo to_s
ruby.require(user); // carregar o arquivo user.rb
RubyObject user = ruby.eval(User.new(Sergio)); // criar um objeto User (do Ruby)
System.out.println(ruby.call(user, to_s, String.class)); // chamar o mtodo to_s

// chamar um mtodo esttico (da classe, que em Ruby chamada de MetaClass)


ruby.call(user.getMetaClass(), sayHi, Sergio);
}

Edio 68 tJava Magazine


Java 68_copia.indb 35

35

17/04/2009 15:30:09

&YQMPSBOEPP+3VCZ

Listagem 8. Cdigo Ruby (user.rb)


# user.rb
class User
def initialize(name)
@name = name
end
def to_s
User: + @name
end
def self.sayHi(name)
puts Hi #{name}
end
end

Listagem 9. Criando o banco de dados e a tabela USERS.

default converte qualquer array do Ruby


para um Object[]. Caso voc precise de um
array Java mais especfico deve passar
para o to_java o tipo a ser convertido, por
exemplo: [a, b, c].to_java(:String) produz
um String[].
H um bug atualmente no JRuby 1.1.6 que faz com
que Strings acentuadas sejam convertidas de forma errada para sua verso em Java. Enquanto esse problema
no resolvido, um workaround utilizar o mtodo to_
java_bytes para explicitamente converter uma String do
Ruby para uma String do Java antes de pass-la para
um mtodo Java. Ex: java_s = Java::JavaLang::String.
new(Srgio.to_java_bytes).

CREATE DATABASE `MyDB`;


grant all privileges on MyDB.* to MyDB@% identified by MyDB;
USE `MyDB`;
CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(100) default NULL,
`password` varchar(100) default NULL,
`email` varchar(100) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Listagem 10. Cdigo do ActiveRecord.


require active_record
ActiveRecord::Base.establish_connection(
:adapter => jdbcmysql,
:host => localhost,
:username => MyDB,
:password => MyDB,
:database => MyDB
)
class User < ActiveRecord::Base
# Voce no precisa fazer nada aqui !!!
# Toda a configurao/mapeamento feito automaticamente via Metaprogramao
end
u = User.new
u.username = saoj
u.email = sergio.oliveira.jr@gmail.com
u.password = abc123
u.save # insert
saoj = User.find_by_username(saoj)
if saoj then puts #{saoj.id}: #{saoj.email} end
saoj.password = abcd1234
saoj.email = sergio@sergio.com.br
saoj.save # update
saoj = User.find_by_username_and_password(saoj, abcd1234);
if saoj then puts #{saoj.id}: #{saoj.email} end
saoj.delete # remover o registro do DB

Para finalizar essa seo, vale pena


mencionar que voc tambm pode herdar
uma classe Java para definir uma nova
classe Ruby (ex: include_class jm.jruby.User;
class PowerUser < User; end) assim como voc
pode implementar uma interface Java em
Ruby (ex: class SomeJRubyObject; include java.
lang.Runnable; end).

Chamando cdigo Ruby a partir do Java


Do ponto de vista do programador Java,
o mais provvel querer chamar um
pouco de Ruby de dentro da sua aplicao
Java. Essa seo analisar como instanciar
objetos Ruby dentro do seu cdigo Java e
como passar objetos Java como parmetros
para mtodos Ruby. O cdigo da Listagem
7 exemplifica como voc pode utilizar a
classe org.jruby.javasupport.JavaEmbedUtils para
esse fim. A Listagem 8 traz o cdigo Ruby
que estamos acessando a partir do nosso
cdigo em Java. Ele deve estar no mesmo
diretrio que a classe Java.
A linha ruby.require(user) da Listagem 7
faz com que o JRuby carregue o arquivo
user.rb com a definio da classe User em
Ruby. A classe JRubyInterpreter pode ser
facilmente transformada em um Singleton
para que ela possa ser obtida em qualquer
ponto da sua aplicao atravs de um mtodo esttico getInstance(). Outras melhorias
que podem ser consideradas: expor mtodos para modificar o loadpath, criar um
mtodo para carregar qualquer arquivo
Ruby do classpath da aplicao e suportar
encadeamento de mtodos (ex: obj.methods.
sort.grep(java)).

36 Java Magazine t Edio 68


Java 68_copia.indb 36

17/04/2009 15:30:09

Concluses
Java e Ruby so linguagens bastante
diferentes, mas graas ao JRuby todo o
poder do Ruby pode ser utilizado dentro
da plataforma Java. Nesse artigo analisamos como possvel integrar cdigo
Java com cdigo Ruby de forma a fazer
chamadas de Java para Ruby e de Ruby
para Java. Vimos tambm como utilizar
o framework ActiveRecord e como aplicaes e frameworks existentes na lin-

guagem Java podem fazer uso do JRuby


de forma bastante transparente.
Apesa r de Ruby possu i r a lg u mas
vantagens em relao linguagem Java,
principalmente no quesito flexibilidade
e expressividade, a plataforma Java se
encontra num nvel de maturidade muito superior plataforma Ruby. O JRuby
surge para unir esses dois mundos,
oferecendo um pouco da mgica de metaprogramao do Ruby para o Java.
Sergio Oliveira Jr
sergio.oliveira.jr@gmail.com
autor dos projetos open-source
Mentawai e Space4J. Trabalhou
no mercado financeiro americano desenvolvendo sistemas de alta-disponibilidade e implementando protocolos para transaes
eletrnicas em tempo real com as principais bolsas do
mundo. Participou das startups Zipmail, ParPerfeito,
Escola24Horas e Selleto. Atualmente trabalha como
consultor independente e investidor privado.

http://www.jruby.org/
Pgina oficial do projeto JRuby
D seu feedback sobre esta edio!
A Java Magazine tem que ser feita ao
seu gosto. Para isso, precisamos saber
o que voc, leitor, acha da revista!

D
s

(na verdade, em Java no nem mesmo


possvel compilar invocaes para um
mtodo inexistente), em Ruby voc pode
tratar qualquer chamada a um objeto
atravs de um mtodo especial chamado method_missing, que recebe o nome e
os parmetros do mtodo inexistente
chamado. O ActiveRecord usa essa funcionalidade para aceitar qualquer tipo
de mtodo find_by_XXXX e extrair do nome
do mtodo os campos que devem ser
procurados. Esse o caso dos mtodos
estticos User.find_by_username e User.find_
by_username_and_password do exemplo.
O ActiveRecord possui tambm muitas outras funcionalidades avanadas,
que no teremos espao para discutir
aqui, como suporte a relacionamentos
one-to-many e many-to-many, campos
contadores, relaes polimrficas, tags,
chaves estrangeiras, etc.

Feedback
eu

D seu voto sobre este artigo, atravs do link:

www.devmedia.com.br/javamagazine/feedback

Edio 68 tJava Magazine


Java 68_copia.indb 37

sobre e
s

O ActiveRecord um famoso framework


de Ruby que implementa o padro Active Record sugerido por Martin Fowler
no seu livro Pat ter ns of Enterprise
Application Architecture. Assim como
o Hibernate no Java, ele uma soluo
ORM para o mapeamento de um objeto
para uma ou mais tabelas de um banco
de dados relacional. Precisaramos de
um livro inteiro para cobrir todos os
aspectos do ActiveRecord, mas basta
analisar suas funcionalidades principais
para perceber como a metaprogramao
de Ruby torna esse framework bastante
simples e intuitivo.
Voc j deve ter instalado as gems
necessrias para rodar o ActiveRecord
com o JRuby (veja a seo Instalando
Gems desse artigo), ento vamos criar
um banco no MySQL que conter uma
tabela simples, USERS. A Listagem 9
mostra o cdigo SQL que voc pode
executar para criar o seu database MyDB
e a sua tabela USERS.
Agora vamos criar uma classe User em
Ruby para acessar a tabela USERS utilizando ActiveRecord. A Listagem 10 mostra o
cdigo do arquivo user.rb que voc pode
colocar em qualquer diretrio e executar
com o comando jruby user.rb.
A primeira coisa que voc deve ter notado sobre o ActiveRecord que no se faz
necessrio qualquer mapeamento entre
os campos do BD e as propriedades do
objeto. Na verdade no nem mesmo necessrio criar as propriedades do objeto
User, pois elas so criadas dinamicamente
pelo ActiveRecord a partir das colunas
da tabela USERS. Devido ao excelente suporte a metaprogramao na linguagem
Ruby, bastante fcil criar variveis e
mtodos de instncia dinamicamente, e
o ActiveRecord faz uso dessa funcionalidade para programar a classe User. Essa
uma flexibilidade importante que infelizmente no possvel de se conseguir
facilmente com a linguagem Java.
Outra mgica da metaprogramao
que qualquer chamada a um mtodo
inexistente pode ser interceptada e
resolvida em tempo de execuo. Ao
invs de receber um NoSuchMethodException

edio
ta

ActiveRecord com JRuby

37

17/04/2009 15:30:15

Вам также может понравиться