A algum tempo atrás eu estava imaginando como seria uma IDE (ou editor de texto se preferir) usando cloud computing, fiquei imaginando como isso funcionaria e como seria agregado as empresas. A algum tempo atraz ouvi falar no Heroku Garden, uma IDE para desenvolvimento na nuvem para RoR, porém aparentemente o projeto foi abandonado. Esses dias olhando no forum do RubyOnBr, um cara comenta de um tal de Bespin, e eu resolvi procurar, eis que me surge o Mozilla Bespin, me registei e começei a brincar, achei o projeto promissor, vc pode criar projetos onde ele lista, vc tem uma linha de comando para utilizar, porém só funciona HTML, tentei usar PHP, Ruby, Java, e infelizmente a IDE ainda está engatinhando, o suporte é bem limitado, mas a interface gráfica é atraente.
Busquei os fontes do projeto e encontrei dois repositorios Mercurial, um para o server-side e um para o client-side, basicamente o backend do projeto roda em python e Java, e o front-end é uma mistura de JavaScript e JSON usando Prototype (pelo menos é parecido), para gerenciar as informações e enviar para o servidor.
baixei ambos os fontes, e estou ainda analisando, o servidor roda usando o virtualenv do python, ou seja emula uma maquina para que possa ser usado o servidor, infelizmente o README é precario quando a instalação, eu que sou leigo no virtualenv, apanhei um pouco até descobrir o easy_install para instalar as dependencias do projeto, ainda estou tentando por a IDE rodar na minha máquina. E acredito que valha a pena dar uma olhadinha no Bespin, mesmo que não haja muito o que fazer.
Parece que temos um projeto interessante saindo do forno.
terça-feira, 24 de novembro de 2009
terça-feira, 17 de novembro de 2009
Objetopolis
Bem Vindo a Objetopolis.
Assim começa o segundo capitulo do livro Java! Use a Cabeça (Se não for também não interessa :P), copiei esse termo do livro, simplemente para ressaltar o que quero dizer.
Existem alguns que dizem que controlar o fluxo da informaçã com IFs é uma quebra ao paradigma orientado a objeto, porém nem todos os casos existe a necessidade de criar uma Interface e/ou ENUM para contornar IFs, salvo em alguns casos. Muitas vezes o excesso de abstrações para forçar/evitar o uso de algumas estruturas de controle ditas não-oo podem tornar o código menos legivel. Eu acredito que a beleza do codigo é grande parte da beleza de um sistema, concerteza um sistema bem escrito será um sistema que conterá a integração continua, e nenhum desenvolvedor que chegar até o sistema vai abandona-lo.
O que eu defendo quando se escreve um software é, pense em como vc vai ler isso aqui daqui a alguns meses, normalmente 1 mês basta para termos vontade de excluir todos os nossos codigos e reafaze-los aplicando novas tecnicas e funções, isso não é regra, mas como qualquer desenvolvedor que se preze está sempre em constante evolução seu novo conhecimento pode melhorar ou ajudar a escrever o codigo de forma mais elegante.
Apesar de tudo que eu disse sobre os IFs, eu não gosto de usa-los, acredito que deixa o código "tosco", existem situações em que ele é necessário. Muitos ifs podem ser evitados como por exemplo:
esse código é facimelmente convertido em uma linha:
Em alguns casos o operador ternário tbm pode ser muito bem empregado, aumentado a legibilidade do código, lembre-se um sistema não é mais definido por linhas de código :D
Algo que eu gosto muito de fazer e usar um pouco de reflection, atrelado a um HasMap, com simples linhas de código temos um código mais legivel, como por exemplo, no item abaixo, abre-se uma determinada tela de um sistema utilizando esse recuro.
voila, temos um código limpo e facil de ser explicado, não existe problema em ler esse codigo, ele é completamente intuitivo, um único if, e um pouco de dinamismo, e lhes apresento um Controller desvinculado a uma tela. e se adiconar um botão não existe necessidade de criar um novo actionListener para abrir uma tela.
PS: esses exemplos foram criados a mão, aqui no blog, as chances disso não compilar são grandes, é meramente ilustrativo
Por isso que ressalto, muitas vezes para usarmos objetos, sempre que existe uma necessidade, cada objeto deve ter suas funções bem definidas, como li um dia o Sergio Taborda disse, se um objeto é somente para ser um apunhado de atributos com getters e setters que seja, desde que ele tenha sua funcionalidade bem definida.
Viajei nesse post, começei criticando algo que eu faço pra defenter o uso de objetos sempre hehhe.
Só mais um detalhe
Esqueçam os tipos primitivos, utilizem os wrappers A perca de performance é minima, e vc trabalha em um nivel superior aos tipos primitivos.
isso aí povo até mais.
Assim começa o segundo capitulo do livro Java! Use a Cabeça (Se não for também não interessa :P), copiei esse termo do livro, simplemente para ressaltar o que quero dizer.
Existem alguns que dizem que controlar o fluxo da informaçã com IFs é uma quebra ao paradigma orientado a objeto, porém nem todos os casos existe a necessidade de criar uma Interface e/ou ENUM para contornar IFs, salvo em alguns casos. Muitas vezes o excesso de abstrações para forçar/evitar o uso de algumas estruturas de controle ditas não-oo podem tornar o código menos legivel. Eu acredito que a beleza do codigo é grande parte da beleza de um sistema, concerteza um sistema bem escrito será um sistema que conterá a integração continua, e nenhum desenvolvedor que chegar até o sistema vai abandona-lo.
O que eu defendo quando se escreve um software é, pense em como vc vai ler isso aqui daqui a alguns meses, normalmente 1 mês basta para termos vontade de excluir todos os nossos codigos e reafaze-los aplicando novas tecnicas e funções, isso não é regra, mas como qualquer desenvolvedor que se preze está sempre em constante evolução seu novo conhecimento pode melhorar ou ajudar a escrever o codigo de forma mais elegante.
Apesar de tudo que eu disse sobre os IFs, eu não gosto de usa-los, acredito que deixa o código "tosco", existem situações em que ele é necessário. Muitos ifs podem ser evitados como por exemplo:
if( c == 0){
return true;
}else{
return false;
}
esse código é facimelmente convertido em uma linha:
return c == 0;
Em alguns casos o operador ternário tbm pode ser muito bem empregado, aumentado a legibilidade do código, lembre-se um sistema não é mais definido por linhas de código :D
Algo que eu gosto muito de fazer e usar um pouco de reflection, atrelado a um HasMap, com simples linhas de código temos um código mais legivel, como por exemplo, no item abaixo, abre-se uma determinada tela de um sistema utilizando esse recuro.
class Controller implements ActionListener{
private Map> botoes = new HashMap >();
public void actionPerformed(ActionEvent e){
Class tela = botoes.get((JButton) e.getSource());
if(tela != null){
criaTela(tela);//Cria a tela para ser mostrada
}else{
raiseErro("Tela não encontrada!"); //monstra erro na tela
}
}
public void registraBotao(JButton botao, Class> tela){
botoes.put(botao, tela);
}
}
voila, temos um código limpo e facil de ser explicado, não existe problema em ler esse codigo, ele é completamente intuitivo, um único if, e um pouco de dinamismo, e lhes apresento um Controller desvinculado a uma tela. e se adiconar um botão não existe necessidade de criar um novo actionListener para abrir uma tela.
PS: esses exemplos foram criados a mão, aqui no blog, as chances disso não compilar são grandes, é meramente ilustrativo
Por isso que ressalto, muitas vezes para usarmos objetos, sempre que existe uma necessidade, cada objeto deve ter suas funções bem definidas, como li um dia o Sergio Taborda disse, se um objeto é somente para ser um apunhado de atributos com getters e setters que seja, desde que ele tenha sua funcionalidade bem definida.
Viajei nesse post, começei criticando algo que eu faço pra defenter o uso de objetos sempre hehhe.
Só mais um detalhe
Esqueçam os tipos primitivos, utilizem os wrappers A perca de performance é minima, e vc trabalha em um nivel superior aos tipos primitivos.
isso aí povo até mais.
segunda-feira, 19 de outubro de 2009
Um poco de RSpec
Estou focando um pouco dos meus estudos em RSpec e BDD, e é incrivel como existe pouco material em portugues sobre o RSpec, então, esse é um post rapido explicando como se validar algumas propriedades dos seus modelos no Rails usando RSpec.
PS: Estou utilizando I18n do Rails para a versão que eu traduzi do rails. seus erros podem estar na versão não traduzida, então o ideal é cuidar, pois seus testes podem não passar.
Validação um campo que deve ser informado.
Esse codigo simula a gravação de uma entidade, e verifica se existe o erro. lembrando que você deve adicionar na classe user:
validando um número
Validanto tamanho de um campo
3 validações básicas para quem ta começando a mexer com o RSpec, não é lá grandes coisas, mas pode ajudar iniciantes em RoR a praticar o BDD.
[]'s
PS: Estou utilizando I18n do Rails para a versão que eu traduzi do rails. seus erros podem estar na versão não traduzida, então o ideal é cuidar, pois seus testes podem não passar.
Validação um campo que deve ser informado.
#Imagine que User é uma classe de usuário qualquer
describe User do
it "should be have an login" do
@user = User.new
@user.save
@user.errors.on(:login).should be_eql("não pode ser em branco")#substitua essa string por seu texto customizado ou pela mensagem padrão em inglês
end
end
Esse codigo simula a gravação de uma entidade, e verifica se existe o erro. lembrando que você deve adicionar na classe user:
class User < ActiveRecord::Base
validates_presence_of :login
end
validando um número
#classe user.rb
validates_numericality_of :age, :only_integer => true
#user_spec.rb
it "should be have a valid number for age" do
@user.age = "a"
@user.save
@user.errors.on(:age).should be_eql("não é um número")
end
Validanto tamanho de um campo
it "should be invalid when the name is greater than 100" do
@user.name = "a"*101
@user.save
@user.errors.on(:name).should be_eql("é muito grande (máximo é 100 caracteres)")
end
#user.rb
validates_length_of :name, :maximum => 100
3 validações básicas para quem ta começando a mexer com o RSpec, não é lá grandes coisas, mas pode ajudar iniciantes em RoR a praticar o BDD.
[]'s
Marcadores:
RSpec,
Ruby On Rails
terça-feira, 29 de setembro de 2009
Rails - Editando o CSS do seu formário uma unica vez
Acredito que todo o desenvolvedor tenha alguns problemas com CSS, ou de esquecer um maldito campo, e ele ficar sem o layout, muitas vezes, todos os campos são renderizados de maneira diferente, de acordo com a definição do designer, ou da equipe.
Normalmente o saco, é por exemplo em rails criar um form da seguinte maneira
PS: Esse código foi escrito em HAML. é bem simples modifica-lo para ERB.
O que vemos é que existem dois campos com a tag :class, que indica a classe do componente para o Rails renderizar na tela. Eis que nessa tela imagine mais uns 10 text_field, e outras páginas de cadastro com quantidades semelhantes de campos. Ai o desgraçado do design resolve mudar o layout (não me levem a mal designer, muitas vezes vocês nos dão raiva mesmo, :D), e para mander compatibilidade ele cria outras tags, e la veio no minimo meio dia de serviço para ajustar esses campos ai para o nova classe (por ex: btext_field).
Mas vamos relembrar um conceito simples do Ruby as classes abertas. Nessa situação é um modulo (module), que gerencia os forms, o querido ActionView::Helpers::FormTagHelper.
Ele é o responsavel por renderizar esses objetos. agora basta simplesmente você alterar esse modulo, veja como fazer (editei no meu environment.rb, como ele não é recarregado tem que para o servidor e iniciar novamente, vocês podem fazer esse código em qualquer lugar)
Caso não conheça o metodo merge dos hash do ruby, seria interessante conhece-lo, dessa maneira, não existe mais a necessidade de definir o atributo :class em cada text_field, essa alteração coloca automáticamente essa informação disponivel. Existem coisa que o ruby faz que surpreendem :D.
Normalmente o saco, é por exemplo em rails criar um form da seguinte maneira
- form_for(@foo) do |f|
%p= f.error_messages
%table
%tr
%td= f.label 'Nome:'
%td= f.text_field :name, :class => :atext_field
%tr
%td= f.label 'Descrição:'
%td= f.text_area :description, :class => :atext_area
%tr
%td= f.submit 'Salvar'
PS: Esse código foi escrito em HAML. é bem simples modifica-lo para ERB.
O que vemos é que existem dois campos com a tag :class, que indica a classe do componente para o Rails renderizar na tela. Eis que nessa tela imagine mais uns 10 text_field, e outras páginas de cadastro com quantidades semelhantes de campos. Ai o desgraçado do design resolve mudar o layout (não me levem a mal designer, muitas vezes vocês nos dão raiva mesmo, :D), e para mander compatibilidade ele cria outras tags, e la veio no minimo meio dia de serviço para ajustar esses campos ai para o nova classe (por ex: btext_field).
Mas vamos relembrar um conceito simples do Ruby as classes abertas. Nessa situação é um modulo (module), que gerencia os forms, o querido ActionView::Helpers::FormTagHelper.
Ele é o responsavel por renderizar esses objetos. agora basta simplesmente você alterar esse modulo, veja como fazer (editei no meu environment.rb, como ele não é recarregado tem que para o servidor e iniciar novamente, vocês podem fazer esse código em qualquer lugar)
module ActionView
module Helpers
module FormTagHelper
def text_field(object_name, method, options={})
super object_name, method, options.merge(:class => :btext_field)
end
def text_area(object_name, method, options={})
super object_name, method, options.merge(:class => :btext_area)
end
def check_box(object_name, method, options={}, checked_value="1", unchecked_value = "0")
super object_name, method, options.merge(:class => :bcheck_box), checked_value, unchecked_value
end
end
end
end
Caso não conheça o metodo merge dos hash do ruby, seria interessante conhece-lo, dessa maneira, não existe mais a necessidade de definir o atributo :class em cada text_field, essa alteração coloca automáticamente essa informação disponivel. Existem coisa que o ruby faz que surpreendem :D.
Marcadores:
Ruby,
Ruby On Rails
segunda-feira, 24 de agosto de 2009
Perf4j - Analise de performance em Java
Acredito que a maioria dos desenvolvedores ao menos uma vez mediu o tempo de execução de um método na aplicação. Para quem como eu meche com Java, muitas vezes recorremos ao System.currentTimeMillis():
A saída desse código é o tempo de execução em milisegundos, bem simples, já é algo ilustrativo para medir o desempenho da aplicação, porém muitas vezes isso não tem todas as informações que gostaríamos de ter.
Eis que algum louco inventou um tal de perf4j, uma biblioteca parecida com o log4j, mas voltada para medir a performance da aplicação (O log4j é uma biblioteca de log). Através do perf4j, é possível até gerar gráficos de desempenho, e ele também mostra o tempo médio de execução dos métodos durante a execução.
Vou mostra uma maneira simples de se usar o perf4j mesclado com o Java Logging API, assim podemos salvar os resultados da performance em um arquivo e lê-los quando precisarmos.
O perf4j funciona baseado na classe StopWatch, e apartir dela podemos gerar as nossas estatísticas. Inicialmente o código vai ficar maior porém os dados que podemos conseguir em cima disso são bem maiores.
OBS: Já tive problemas com essa manipulação de arquivos e locks do Sistema operacional, quando estamos trabalhando com arquivos, o ideal é sincronizar e tornar a leitura do arquivo Thread Safe
Após a execução da ultima linha algo como:
24/08/2009 13:43:32 org.perf4j.javalog.JavaLogStopWatch log
INFO: start[1251132212406] time[406] tag[Teste]
Deverá ser exibido na console. Essa saída é até menos legível que a do System.currentTimeMillis(), porém o poder do per4j será mostrado a seguir.
Vamos ler o arquivo de log gerado, seria interessante executar mais alguns métodos para armazenar no log, o per4j trabalha com uma classe chamada LogParser para gerar estatísticas em cima do arquivo de log gerado (statistics.log).
A criação do LogParser é simples, primeiro argumento é o arquivo de log que geramos através do StopWatch, o segundo é o arquivo temporário a ser salvo, o terceiro parâmetro (null) é utilizado para gráficos, os outros dois parametros não vem ao caso agora, o ultimo parâmetro é o formatador do arquivo temporário, define o layout do arquivo.
O método parseLog faz a leitura do arquivo. Agora basta você ver o arquivo lido.log e termos o arquivo legível trazendo a media de tempo de execução do arquivo (Avg), o tempo mínimo (Min), o tempo máximo (Max), a quantidade de vezes que o método foi chamado (Count). Agora sim as informações são bem maiores não acham?
Aconselho o uso do perf4j, excelente ferramenta para analise de performance em Java.
Long agora = System.currentTimeMillis();
//Algum método demorado
System.out.println((System.currentTimeMillis()-agora)+"ms");
A saída desse código é o tempo de execução em milisegundos, bem simples, já é algo ilustrativo para medir o desempenho da aplicação, porém muitas vezes isso não tem todas as informações que gostaríamos de ter.
Eis que algum louco inventou um tal de perf4j, uma biblioteca parecida com o log4j, mas voltada para medir a performance da aplicação (O log4j é uma biblioteca de log). Através do perf4j, é possível até gerar gráficos de desempenho, e ele também mostra o tempo médio de execução dos métodos durante a execução.
Vou mostra uma maneira simples de se usar o perf4j mesclado com o Java Logging API, assim podemos salvar os resultados da performance em um arquivo e lê-los quando precisarmos.
O perf4j funciona baseado na classe StopWatch, e apartir dela podemos gerar as nossas estatísticas. Inicialmente o código vai ficar maior porém os dados que podemos conseguir em cima disso são bem maiores.
OBS: Já tive problemas com essa manipulação de arquivos e locks do Sistema operacional, quando estamos trabalhando com arquivos, o ideal é sincronizar e tornar a leitura do arquivo Thread Safe
String arquivo = "statistics.log";//nome do arquivo que será armazena as estatisticas
Logger logger = Logger.getLogger("com.rollingwithcode");//Qualquer pacote serve.
logger.addHandler(new FileHandler(arquivo));//adiciona ao log o arquivo como handler, a Java Logging API, usa esse arquivo para armazenar o log.
StopWatch stop = new JavaLogStopWatch("Teste", logger);//o primeiro argumento é o nome ilustrativo desse log, cada método deve ter seu próprio nome, assim se torna mais intuitivo e mais especifico quando se lê o arquivo.
//Aqui vem alguma execução que pode ser demorada.
stop.stop();
Após a execução da ultima linha algo como:
24/08/2009 13:43:32 org.perf4j.javalog.JavaLogStopWatch log
INFO: start[1251132212406] time[406] tag[Teste]
Deverá ser exibido na console. Essa saída é até menos legível que a do System.currentTimeMillis(), porém o poder do per4j será mostrado a seguir.
Vamos ler o arquivo de log gerado, seria interessante executar mais alguns métodos para armazenar no log, o per4j trabalha com uma classe chamada LogParser para gerar estatísticas em cima do arquivo de log gerado (statistics.log).
String arquivo = "statistics.log";
String temp = "lido.log";//Arquivo temporário, os dados são jogados do statistics para esse outro arquivo de log.
LogParser parser = new LogParser(new BufferedReader(new FileReader(arquivo)),
new PrintStream(new FileOutputStream(temp), true), null, 30000L, false,
new GroupedTimingStatisticsTextFormatter());
parser.parseLog();
A criação do LogParser é simples, primeiro argumento é o arquivo de log que geramos através do StopWatch, o segundo é o arquivo temporário a ser salvo, o terceiro parâmetro (null) é utilizado para gráficos, os outros dois parametros não vem ao caso agora, o ultimo parâmetro é o formatador do arquivo temporário, define o layout do arquivo.
O método parseLog faz a leitura do arquivo. Agora basta você ver o arquivo lido.log e termos o arquivo legível trazendo a media de tempo de execução do arquivo (Avg), o tempo mínimo (Min), o tempo máximo (Max), a quantidade de vezes que o método foi chamado (Count). Agora sim as informações são bem maiores não acham?
Aconselho o uso do perf4j, excelente ferramenta para analise de performance em Java.
segunda-feira, 10 de agosto de 2009
.COM
Agora o Blog é .COM :)
Continua sendo hospedado no blogger, mas para acessar ficou mais facil
RollingWithCode.com
Esse post é só pra falar isso outra hora posto algo util :)
[]'s
Continua sendo hospedado no blogger, mas para acessar ficou mais facil
RollingWithCode.com
Esse post é só pra falar isso outra hora posto algo util :)
[]'s
sexta-feira, 31 de julho de 2009
Java ScriptEngine
Estava eu pensando esses dias, se posso executar código java via Jruby por que não o contrário? Quais as minhas chances de usar Jruby dentro do Java?
Então la fui eu ao oraculo, e começei a buscar, ouvi falar de um JSR XXX (preencha com o número que quiser, nunca me lembro desses números, que pra mim são irrelevantes), que define o Java ScriptEngine, que nada mais é do que usar scripts dentro do Java, no Java 6, já vem com superte a Rhino (JavaScript), embutido, mas exemplos usando JavaScript tem de monte, vou lhes mostrar como instanciar uma classe via JRuby e chamar alguns metodos dessa classe no java. Não vou dizer que isso vai ficar bom, mas enfim, quem sabe melhorem futuramente essas engines, Mesmo assim você não precisa massacrar seu codigo java para migra-lo para JRuby, pode simplemente adaptar o codigo do JRuby no Java. Vamos ao exemplo, primeiramente vejamos quais nossas engines disponiveis na nossa versão.
A saida deve ser Mozilla Rhino, lembre-se java 6, eu não tenho bem certeza, mas acho que o ScriptEngine está disponivel na versão 5, porém sem nenhuma engine disponivel.
E ai tio e agora como que nos faz?
Vamos adicionar o Jruby, no site do projeto baixem os script-engines, com isso temos as libs de diversas linguagens suportadas que podemos utilizar, para nos interessa, o que esta dentro da pasta jruby/build, o jruby-engine.jar deve ser adicionado ao seu classpath, ainda existem outro jar a ser adicionado, se você olhar outros tutoriais, ele vai passar diversos jar que não estão mais no $JRUBY_HOME/lib, ignore :), adicione ao classpath do seu projeto somente o jruby.jar, e agora sim. Se executar o programinha de antes deve aparecer agora
Vamos para o nosso querido Hello World (eu sei, eu sei, todos vocês amam o Hello World (: )
ao executar temos a mesma saida do Println, não é magico? Heeheh, um puts executado via java. Sei exatamente o que a maioria pensou, vou ter que por todo o codigo Jruby num String? A reposta é não :), a não ser que você queira fazer isso, mas eu não aconselho.
Existem outros metodos para recuperar as engines, e um deles é por extensão, poderiamos ter usado o metodo getEngineByExtension e passar como parametro o “rb”, e teriamos o Jruby.
Vamos criar então uma classe bem bunito um arquivo .rb
Lembrando que o toString sobrescreve o metodo toString do java sem problemas algum, os metodos set_ foram definidos para seguir as convensões do ruby, e isso vai tornar nosso codigo java feio, e não digam que não avisei. Vamos criar uma pequena interface
notem o estilo que foi declarado os metodos set_ na interface tbm, deve haver alguma maneira de fazer isso automatico, se alguem souber me avisa :)
E agora tio? Vamos brincar um pouco de ScriptEngine?
E adivinhem a saida:
Tudo isso só pra misturar um pouco de Ruby com java, credo, parece coisa de loco :)
vou investigar mais algo, e ver se existem maneiras de melhorar isso.
Abraços até a próxima
Então la fui eu ao oraculo, e começei a buscar, ouvi falar de um JSR XXX (preencha com o número que quiser, nunca me lembro desses números, que pra mim são irrelevantes), que define o Java ScriptEngine, que nada mais é do que usar scripts dentro do Java, no Java 6, já vem com superte a Rhino (JavaScript), embutido, mas exemplos usando JavaScript tem de monte, vou lhes mostrar como instanciar uma classe via JRuby e chamar alguns metodos dessa classe no java. Não vou dizer que isso vai ficar bom, mas enfim, quem sabe melhorem futuramente essas engines, Mesmo assim você não precisa massacrar seu codigo java para migra-lo para JRuby, pode simplemente adaptar o codigo do JRuby no Java. Vamos ao exemplo, primeiramente vejamos quais nossas engines disponiveis na nossa versão.
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
public class Main {
public static void main(String[] args) throws Exception{
ScriptEngineManager manager = new ScriptEngineManager();
for(ScriptEngineFactory factory : manager.getEngineFactories()){
System.out.println(factory.getEngineName());
}
}
}
A saida deve ser Mozilla Rhino, lembre-se java 6, eu não tenho bem certeza, mas acho que o ScriptEngine está disponivel na versão 5, porém sem nenhuma engine disponivel.
E ai tio e agora como que nos faz?
Vamos adicionar o Jruby, no site do projeto baixem os script-engines, com isso temos as libs de diversas linguagens suportadas que podemos utilizar, para nos interessa, o que esta dentro da pasta jruby/build, o jruby-engine.jar deve ser adicionado ao seu classpath, ainda existem outro jar a ser adicionado, se você olhar outros tutoriais, ele vai passar diversos jar que não estão mais no $JRUBY_HOME/lib, ignore :), adicione ao classpath do seu projeto somente o jruby.jar, e agora sim. Se executar o programinha de antes deve aparecer agora
Mozilla Rhino
Jruby Engine
Vamos para o nosso querido Hello World (eu sei, eu sei, todos vocês amam o Hello World (: )
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Main {
public static void main(String[] args) throws Exception{
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("jruby");//Buscamos a Engine do Jruby
engine.eval("puts 'Hello World'");//Codigo JRuby
}
}
ao executar temos a mesma saida do Println, não é magico? Heeheh, um puts executado via java. Sei exatamente o que a maioria pensou, vou ter que por todo o codigo Jruby num String? A reposta é não :), a não ser que você queira fazer isso, mas eu não aconselho.
Existem outros metodos para recuperar as engines, e um deles é por extensão, poderiamos ter usado o metodo getEngineByExtension e passar como parametro o “rb”, e teriamos o Jruby.
Vamos criar então uma classe bem bunito um arquivo .rb
class Teste
attr_accessor :name, :age
def set_name(name)
self.name = name
end
def set_age(age)
self.age = age
end
def toString
self.name+" "+self.age.to_s
end
end
Lembrando que o toString sobrescreve o metodo toString do java sem problemas algum, os metodos set_ foram definidos para seguir as convensões do ruby, e isso vai tornar nosso codigo java feio, e não digam que não avisei. Vamos criar uma pequena interface
public interface Teste {
String name();
void set_name(String name);
Integer age();
void set_age(Integer age);
}
notem o estilo que foi declarado os metodos set_ na interface tbm, deve haver alguma maneira de fazer isso automatico, se alguem souber me avisa :)
E agora tio? Vamos brincar um pouco de ScriptEngine?
public static void main(String[] args) throws Exception{
ScriptEngineManager manager = new ScriptEngineManager();
for(ScriptEngineFactory factory : manager.getEngineFactories()){
System.out.println(factory.getEngineName());
}
ScriptEngine engine = manager.getEngineByName("jruby");
engine.eval(new FileReader("src/com/rollingwithcode/testejruby/teste.rb"));//arquivo .rb
Object instance = engine.eval("@teste = Teste.new");//crio a instancia
Invocable inv = (Invocable) engine;
Teste teste = inv.getInterface(instance, Teste.class); //converto a classe em uma Interface Java
teste.set_name("Rafael");
teste.set_age(21);
System.out.println(teste.toString());
System.out.println(teste.name());
}
E adivinhem a saida:
Rafael 21
Rafael
Tudo isso só pra misturar um pouco de Ruby com java, credo, parece coisa de loco :)
vou investigar mais algo, e ver se existem maneiras de melhorar isso.
Abraços até a próxima
Marcadores:
Java,
JRuby,
Ruby,
ScripEngine
Assinar:
Postagens (Atom)
