Jruby - Ruby em Ambientes 100% Java
Upcoming SlideShare
Loading in...5
×
 

Jruby - Ruby em Ambientes 100% Java

on

  • 2,441 views

Apresentação realizada no CaelumDay RJ 2011 (02/07/2011)

Apresentação realizada no CaelumDay RJ 2011 (02/07/2011)

Statistics

Views

Total Views
2,441
Views on SlideShare
2,435
Embed Views
6

Actions

Likes
4
Downloads
32
Comments
2

3 Embeds 6

https://www.linkedin.com 3
http://www.linkedin.com 2
http://paper.li 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Jruby - Ruby em Ambientes 100% Java Jruby - Ruby em Ambientes 100% Java Presentation Transcript

  • Tirando o máximo da JVM com Ruby Hugo Roque Sergio Azevedo Junior hugo.roque@caelum.com.br sergio.junior@caelum.com.br hugolnx.com sagadoprogramador.com.br @hugolnx @sergioazevedoSaturday, July 2, 2011
  • Nós não somos o Douglas Campos @qmxSaturday, July 2, 2011
  • Tirando o máximo da JVM com Ruby Hugo Roque Sergio Azevedo Junior hugo.roque@caelum.com.br sergio.junior@caelum.com.br hugolnx.com sagadoprogramador.com.br @hugolnx @sergioazevedoSaturday, July 2, 2011
  • Ruby em Ambientes 100% Java Hugo Roque Sergio Azevedo Junior hugo.roque@caelum.com.br sergio.junior@caelum.com.br hugolnx.com sagadoprogramador.com.br @hugolnx @sergioazevedoSaturday, July 2, 2011
  • JavaSaturday, July 2, 2011
  • 10 anos de mercado multiplataforma compilado JVM Java bibliotecas frameworks JIT estático comunidadeSaturday, July 2, 2011
  • Java - classe Tarefa public class Tarefa{ private Long id; private String descricao; private Calendar dataFinalizacao; public Long getId(){ return this.id; } public void setId(Long id){ this.id = id; } public String getDescricao(){ return this.descricao; } public void setDescricao(String descricao){ this.descricao = descricao; } public String getDataFinalizacao(){ return this.dataFinalizacao; } public void setDataFinalizacao(Calendar novaData){ this.dataFinalizacao = novaData; } }Saturday, July 2, 2011
  • Java - Usando a classe Tarefa public class TesteTarefa{ public static void main(String[] args){ Tarefa tarefa = new Tarefa(); tarefa.setId(10); tarefa.setDescricao("Criar gerenciador de tarefa"); System.out.println("tarefa:"+tarefa.getId()+ "-" + tarefa.getDescricao()); } }Saturday, July 2, 2011
  • RubySaturday, July 2, 2011
  • dinâmico poderoso interpretado elegante Ruby modinha flexivel comunidade emo Orientado a ObjetosSaturday, July 2, 2011
  • dinâmico poderoso interpretado elegante Ruby hum..vai dizer que Java não serve mais? modinha flexivel comunidade emo Orientado a ObjetosSaturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa def getId() return @id end def setId(id) @id = id end def getDescricao() return @descricao end def setDescricao(descricao) @descricao = descricao end def getDataFinalizacao() return @dataFinalizacao end def setDataFinalizacao(novaData) @dataFinalizacao = novaData; end endSaturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa def getId() return @id A grande vantagem então é não end declarar os tipos das variaveis e def setId(id) @id = id niveis de acesso? end def getDescricao() return @descricao end def setDescricao(descricao) @descricao = descricao end def getDataFinalizacao() return @dataFinalizacao end def setDataFinalizacao(novaData) @dataFinalizacao = novaData; end endSaturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa def getId() return @id end Existem vantagens como def setId(id) expressividade @id = id end def getDescricao() return @descricao end def setDescricao(descricao) @descricao = descricao end def getDataFinalizacao() return @dataFinalizacao end def setDataFinalizacao(novaData) @dataFinalizacao = novaData; end endSaturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa def getId() return @id end Existem vantagens como def setId(id) expressividade @id = id end def getDescricao() return @descricao end def setDescricao(descricao) @descricao = descricao end def getDataFinalizacao() return @dataFinalizacao end def setDataFinalizacao(novaData) @dataFinalizacao = novaData; end endSaturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa def id return @id end def id=(id) @id = id end def descricao return @descricao end def descricao=(descricao) @descricao = descricao end def data_finalizacao return @data_finalizacao end def data_finalizacao=(novaData) @data_finalizacao = novaData; end endSaturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa def id return @id end def id=(id) @id = id end def descricao return @descricao end def descricao=(descricao) @descricao = descricao end def data_finalizacao return @data_finalizacao end def data_finalizacao=(novaData) @data_finalizacao = novaData; end endSaturday, July 2, 2011
  • Ruby - Usando a classe Tarefa tarefa = Tarefa.new tarefa.id = 10 tarefa.descricao = "Criar gerenciador de tarefa" puts "tarefa: #{tarefa.id} - #{tarefa.descricao}"Saturday, July 2, 2011
  • Ruby - Usando a classe Tarefa r’s tarefa = Tarefa.new Se tte tarefa.id = 10 tarefa.descricao = "Criar gerenciador de tarefa" puts "tarefa: #{tarefa.id} - #{tarefa.descricao}"Saturday, July 2, 2011
  • Ruby - Usando a classe Tarefa r’s tarefa = Tarefa.new Se tte tarefa.id = 10 tarefa.descricao = "Criar gerenciador de tarefa" puts "tarefa: #{tarefa.id} - #{tarefa.descricao}" ’s et ter G Parênteses opcionais + Syntax Sugar = código mais expressivo.Saturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa def id return @id end def id=(id) @id = id end def descricao return @descricao end def descricao=(descricao) @descricao = descricao end def data_finalizacao return @data_finalizacao end def data_finalizacao=(novaData) @data_finalizacao = novaData; end endSaturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa def id return @id end def id=(id) @id = id end def descricao return @descricao end def descricao=(descricao) @descricao = descricao end def data_finalizacao return @data_finalizacao end def data_finalizacao=(novaData) @data_finalizacao = novaData; end endSaturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa def id return @id end Com metaprogramação diga def id=(id) @id = id adeus aos repetidos “get’s/set’s” end def descricao return @descricao end def descricao=(descricao) @descricao = descricao end def data_finalizacao return @data_finalizacao end def data_finalizacao=(novaData) @data_finalizacao = novaData; end endSaturday, July 2, 2011
  • Ruby - classe Tarefa class Tarefa attr_accessor :id, :descricao, :data_finalizacao end hahahahaha. Hum....Saturday, July 2, 2011
  • E com Banco de Dados?Saturday, July 2, 2011
  • Java - classe Tarefa com Hibernate @Entity class Tarefa{ @Id @GeneratedValue private Long id; private String descricao; private Calendar dataFinalizacao; public Long getId(){ return this.id; } public void setId(Long id){ this.id = id; } public String getDescricao(){ return this.descricao; } public void setDescricao(String descricao){ this.descricao = descricao; } public String getDataFinalizacao(){ return this.dataFinalizacao; } ... }Saturday, July 2, 2011
  • Ruby - classe Tarefa com BD class Tarefa < ActiveRecord::Base end Menos código aindaSaturday, July 2, 2011
  • E com Aplicações Web?Saturday, July 2, 2011
  • Web Dev - Java x RubySaturday, July 2, 2011
  • Vamos largar o Java e migrar para Ruby e Rails ?!Saturday, July 2, 2011
  • Mas antes, Tem coisas que precisamos saber.Saturday, July 2, 2011
  • Ruby - Desvantagens ‣ Performance ‣ Ruby é lento, =~ 10x mais lento que Java ‣ Totalmente interpretado (sem JIT Compiler) ref: http://shootout.alioth.debian.org/u64q/benchmark.php?test=all&lang=yarv&lang2=javaSaturday, July 2, 2011
  • Ruby - Desvantagens ‣ Garbage Collection ‣ Não eficiente para aplicações Server Side. “ 99.999% is a bit over-exaggerated, but it is true that garbage collection algorithm of YARV and MRI focus for throughput on non-memory extensive short-running programs, and GC of REE is not suitable for those programs.” Yukihiro Matsumoto ref: http://www.ruby-forum.com/topic/215163#934681 ref: http://jabberwocky.eu/2010/09/03/ruby-garbage-collection/Saturday, July 2, 2011
  • Ruby/Rails - DesvantagensSaturday, July 2, 2011
  • Ruby/Rails - Desvantagens Deploy ‣ Heroku ‣ https://github.com/heroku/herokuSaturday, July 2, 2011
  • Ruby/Rails - Desvantagens Deploy o é gem Nã ta ‣ Heroku van des ‣ https://github.com/heroku/herokuSaturday, July 2, 2011
  • Ruby/Rails - Desvantagens Deploy o é gem Nã ta ‣ Heroku van des ‣ https://github.com/heroku/heroku ‣ Engine Yard ‣ https://github.com/engineyard/engineyardSaturday, July 2, 2011
  • Ruby/Rails - Desvantagens Deploy o é gem Nã ta ‣ Heroku van des ‣ https://github.com/heroku/heroku ‣ Engine Yard não m ém age amb ant ‣ https://github.com/engineyard/engineyard T esv é dSaturday, July 2, 2011
  • Ruby/Rails - Desvantagens Deploy o é gem Nã ta ‣ Heroku van des ‣ https://github.com/heroku/heroku ‣ Engine Yard não m ém age amb ant ‣ https://github.com/engineyard/engineyard T esv é d ‣ Outros ‣ capistrano? ‣ rpm? ‣ deb?Saturday, July 2, 2011
  • Ruby/Rails - Desvantagens Deploy o é gem Nã ta ‣ Heroku van des ‣ https://github.com/heroku/heroku ‣ Engine Yard não m ém age amb ant ‣ https://github.com/engineyard/engineyard T esv é d ‣ Outros ‣ capistrano? sim ‣ rpm? A qui pode a cê blem vo ro ‣ deb? r p teSaturday, July 2, 2011
  • Java = Burocrático Ruby/Rails = lento E agora?Saturday, July 2, 2011
  • Java = Burocrático Ruby/Rails = lento E agora? Só falta mudar pra .netSaturday, July 2, 2011
  • .net ??? Tira essa farda preta porque você é moleque!!!Saturday, July 2, 2011
  • Uma implementação 100% Java da linguagem RubySaturday, July 2, 2011
  • Java como plataforma ref: http://www.slideshare.net/sifra/jruby-enterprise-20Saturday, July 2, 2011
  • JRuby - FeaturesSaturday, July 2, 2011
  • JRuby - Features ‣ Roda na JVM ‣ Threads Nativas ‣ JIT ( Just In Time compiler ) ‣ O melhor GC do mundoSaturday, July 2, 2011
  • JRuby - Features ‣ Roda na JVM ‣ Threads Nativas ‣ JIT ( Just In Time compiler ) ‣ O melhor GC do mundo ‣ Permite o uso das bibliotecas e classes Java ‣ JDBC, Servlets, Hibernate ‣ seus prórprios JAR’sSaturday, July 2, 2011
  • JRuby - Features ‣ Roda na JVM ‣ Threads Nativas ‣ JIT ( Just In Time compiler ) ‣ O melhor GC do mundo ‣ Permite o uso das bibliotecas e classes Java ‣ JDBC, Servlets, Hibernate ‣ seus prórprios JAR’s ‣ Suporta RubygemsSaturday, July 2, 2011
  • JRuby - Features ‣ Roda na JVM ‣ Threads Nativas ‣ JIT ( Just In Time compiler ) ‣ O melhor GC do mundo ‣ Permite o uso das bibliotecas e classes Java ‣ JDBC, Servlets, Hibernate ‣ seus prórprios JAR’s ‣ Suporta Rubygems ‣ Suporta RailsSaturday, July 2, 2011
  • JRuby - Features ‣ Roda na JVM ‣ Threads Nativas ‣ JIT ( Just In Time compiler ) ‣ O melhor GC do mundo ‣ Permite o uso das bibliotecas e classes Java ‣ JDBC, Servlets, Hibernate ‣ seus prórprios JAR’s ‣ Suporta Rubygems ‣ Suporta Rails ‣ Deixa até você usar Ruby com WindowsSaturday, July 2, 2011
  • Legal! Mas e aquele papo de Ruby no Java?Saturday, July 2, 2011
  • Vejamos algumas situações do dia a diaSaturday, July 2, 2011
  • JRuby - Cenário 1 Importar planilha Empresa 100% Java precisa fazer uma carga de dados a partir de uma planilha excel.Saturday, July 2, 2011
  • Uma solução comum seria usar Java + Apache POI ref: http://poi.apache.orgSaturday, July 2, 2011
  • Importar Planilha - Java + Apache POI import org.apache.poi.hssf.usermodel.*; //mais imports public class ExcelReadExample { public static void main(String[] args) throws Exception { String filename = "..data.xls"; List sheetData = new ArrayList(); FileInputStream fis = null; try { fis = new FileInputStream(filename); HSSFWorkbook workbook = new HSSFWorkbook(fis); HSSFSheet sheet = workbook.getSheetAt(0); Iterator rows = sheet.rowIterator(); while (rows.hasNext()) { HSSFRow row = (HSSFRow) rows.next(); Iterator cells = row.cellIterator(); List data = new ArrayList(); while (cells.hasNext()) { HSSFCell cell = (HSSFCell) cells.next(); data.add(cell); } sheetData.add(data); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { fis.close(); } } showExelData(sheetData); } //mais código aindaSaturday, July 2, 2011
  • Importar Planilha - Java + Apache POI import org.apache.poi.hssf.usermodel.*; //mais imports public class ExcelReadExample { public static void main(String[] args) throws Exception { String filename = "..data.xls"; List sheetData = new ArrayList(); FileInputStream fis = null; try { fis = new FileInputStream(filename); HSSFWorkbook workbook = new HSSFWorkbook(fis); HSSFSheet sheet = workbook.getSheetAt(0); Iterator rows = sheet.rowIterator(); while (rows.hasNext()) { HSSFRow row = (HSSFRow) rows.next(); Iterator cells = row.cellIterator(); List data = new ArrayList(); while (cells.hasNext()) { HSSFCell cell = (HSSFCell) cells.next(); data.add(cell); } sheetData.add(data); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { fis.close(); } } showExelData(sheetData); } //mais código aindaSaturday, July 2, 2011
  • JRuby pode desburocratizar este códigoSaturday, July 2, 2011
  • Importar Planilha - JRuby + Apache POI require java require "lib/dom4j-1.6.1" require "lib/poi-3.7-20101029" require "lib/poi-ooxml-3.7-20101029" require "lib/poi-ooxml-schemas-3.7-20101029" require "lib/xmlbeans-2.3.0" //imports inp = FileInputStream.new(./dados.xlsx) wb = WorkbookFactory.create(inp) sheet = wb.sheet_at 0 nomes = [] rows = sheet.rowIterator() rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell end end nomes.each{ |nome| puts nome }Saturday, July 2, 2011
  • Importar Planilha - JRuby + Apache POI require java require "lib/dom4j-1.6.1" require "lib/poi-3.7-20101029" require "lib/poi-ooxml-3.7-20101029" require "lib/poi-ooxml-schemas-3.7-20101029" require "lib/xmlbeans-2.3.0" //imports inp = FileInputStream.new(./dados.xlsx) wb = WorkbookFactory.create(inp) sheet = wb.sheet_at 0 nomes = [] rows = sheet.rowIterator() rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell end end nomes.each{ |nome| puts nome }Saturday, July 2, 2011
  • Importar Planilha - JRuby + Apache POI require java require "lib/dom4j-1.6.1" require "lib/poi-3.7-20101029" require "lib/poi-ooxml-3.7-20101029" require "lib/poi-ooxml-schemas-3.7-20101029" require "lib/xmlbeans-2.3.0" //imports inp = FileInputStream.new(./dados.xlsx) wb = WorkbookFactory.create(inp) sheet = wb.sheet_at 0 nomes = [] rows = sheet.rowIterator() rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell end end nomes.each{ |nome| puts nome }Saturday, July 2, 2011
  • Importar Planilha - JRuby + Apache POI require java require "lib/dom4j-1.6.1" require "lib/poi-3.7-20101029" require "lib/poi-ooxml-3.7-20101029" require "lib/poi-ooxml-schemas-3.7-20101029" require "lib/xmlbeans-2.3.0" //imports inp = FileInputStream.new(./dados.xlsx) wb = WorkbookFactory.create(inp) sheet = wb.sheet_at 0 nomes = [] rows = sheet.rowIterator() rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell end end nomes.each{ |nome| puts nome }Saturday, July 2, 2011
  • Importar Planilha - JRuby + Apache POI require java require "lib/dom4j-1.6.1" require "lib/poi-3.7-20101029" require "lib/poi-ooxml-3.7-20101029" require Melhorou mas não se esqueça: "lib/poi-ooxml-schemas-3.7-20101029" require "lib/xmlbeans-2.3.0" Com JRuby você pode usar gems //imports inp = FileInputStream.new(./dados.xlsx) wb = WorkbookFactory.create(inp) sheet = wb.sheet_at 0 nomes = [] rows = sheet.rowIterator() rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell end end nomes.each{ |nome| puts nome }Saturday, July 2, 2011
  • jruby-poi ref: http://github.com/kameeoze/jruby-poiSaturday, July 2, 2011
  • Importar Planilha - JRuby + jruby-poi require rubygems require poi workbook = POI::Workbook.open(./dados.xlsx) rows = workbook.worksheets.first.rows nomes = [] rows.each do |row| nomes << row[0].value unless row.index == 0 end nomes.each{ |nome| puts nome }Saturday, July 2, 2011
  • Importar Planilha - JRuby + jruby-poi require rubygems require poi workbook = POI::Workbook.open(./dados.xlsx) rows = workbook.worksheets.first.rows nomes = [] rows.each do |row| nomes << row[0].value unless row.index == 0 end nomes.each{ |nome| puts nome }Saturday, July 2, 2011
  • Importar Planilha - JRuby + jruby-poi require rubygems require poi workbook = POI::Workbook.open(./dados.xlsx) rows = workbook.worksheets.first.rows nomes = [] rows.each do |row| nomes << row[0].value unless row.index == 0 end nomes.each{ |nome| puts nome }Saturday, July 2, 2011
  • Importar Planilha - JRuby + jruby-poi require rubygems require poi workbook = POI::Workbook.open(./dados.xlsx) rows = workbook.worksheets.first.rows nomes = [] rows.each do |row| nomes << row[0].value unless row.index == 0 end nomes.each{ |nome| puts nome }Saturday, July 2, 2011
  • Importar Planilha - JRuby + jruby-poi require rubygems require poi workbook = POI::Workbook.open(./dados.xlsx) rows = workbook.worksheets.first.rows nomes = [] rows.each do |row| nomes << row[0].value unless row.index == 0 end nomes.each{ |nome| puts nome } Gem Wins!!!Saturday, July 2, 2011
  • JRuby - Cenário 2 Criar Web Service Empresa 100% Java Precisa expor os dados de sua aplicação Web Struts2 na webSaturday, July 2, 2011
  • Uma solução sofisticada seria usar: Java + JAX-RS http://jsr311.java.net/nonav/releases/1.1/index.htmlSaturday, July 2, 2011
  • Web Service- Java + JAX-RS //imports aqui... @Path("/tarefa") public class TarefaResource { private Session session; @Context private UriInfo uriInfo; public TarefaResource() { this.session = new HibernateUtil().getSession(); } @GET @Path("{sigla}") @Produces( {MediaType.APPLICATION_XML }) public String getTarefas() { TarefaDao dao = new TarefaDao(this.session); Tarefa Tarefa = dao.listaTarefas(); String xml = new TarefaXMLAssembler().convertTarefaToXML(Tarefa, uriInfo); return xml; } //... }Saturday, July 2, 2011
  • Web Services JRuby WaySaturday, July 2, 2011
  • JRuby - Sinatra Sinatra é uma DSL para criação de aplicações web. ref: http://www.sinatrarb.com/ ref: https://github.com/sinatra/sinatra/Saturday, July 2, 2011
  • Web Service- Estrutura do projetoSaturday, July 2, 2011
  • Web Service- JRuby + Sinatra require rubygems require sinatra require java config.ru require jruby-rack require lib/fj21-tarefas require lib/mysql-connector-java-5.1.7-bin require lib/xstream-1.3 import br.com.caelum.tarefas.dao.TarefaDAO import br.com.caelum.tarefas.modelo.Tarefa import com.thoughtworks.xstream.XStream import com.thoughtworks.xstream.io.xml.DomDriver import java.util.List get /tarefas do tarefas = TarefaDAO.new.lista serializer = XStream.new(DomDriver.new) serializer.alias(tarefas, List.java_class) serializer.alias(tarefa, Tarefa.java_class) [200,{"Content-Type"=>"application/xml"}, serializer.to_xml(tarefas)] end set :environment, :production run Sinatra::ApplicationSaturday, July 2, 2011
  • Web Service- JRuby + Sinatra require rubygems require sinatra require java config.ru require jruby-rack require lib/fj21-tarefas require lib/mysql-connector-java-5.1.7-bin require lib/xstream-1.3 import br.com.caelum.tarefas.dao.TarefaDAO import br.com.caelum.tarefas.modelo.Tarefa import com.thoughtworks.xstream.XStream import com.thoughtworks.xstream.io.xml.DomDriver import java.util.List get /tarefas do tarefas = TarefaDAO.new.lista serializer = XStream.new(DomDriver.new) serializer.alias(tarefas, List.java_class) serializer.alias(tarefa, Tarefa.java_class) [200,{"Content-Type"=>"application/xml"}, serializer.to_xml(tarefas)] end set :environment, :production run Sinatra::ApplicationSaturday, July 2, 2011
  • JRuby - Sinatra para executar o projeto basta fazer um: rackup e um servidor será iniciado na porta 9292 de localhost ref: http://www.sinatrarb.com/ ref: https://github.com/sinatra/sinatra/Saturday, July 2, 2011
  • JRuby - Sinatra Ao fazer a requisição: curl localhost:9292/tarefas obteremos a seguinte resposta:Saturday, July 2, 2011
  • Muito Bom! Mas como eu faço deploy no Tomcat?Saturday, July 2, 2011
  • warbler ref: https://github.com/nicksieger/warblerSaturday, July 2, 2011
  • JRuby - Warbler gem install warblerSaturday, July 2, 2011
  • JRuby - Warbler gem install warbler warble configSaturday, July 2, 2011
  • JRuby - Warbler Warbler::Config.new do |config| warble.rb config.dirs = %w(lib) config.includes = FileList["server.rb"] config.war_name = "tarefasWS" endSaturday, July 2, 2011
  • JRuby - Warbler Warbler::Config.new do |config| warble.rb config.dirs = %w(lib) config.includes = FileList["server.rb"] config.war_name = "tarefasWS" endSaturday, July 2, 2011
  • JRuby - Warbler Warbler::Config.new do |config| warble.rb config.dirs = %w(lib) config.includes = FileList["server.rb"] config.war_name = "tarefasWS" endSaturday, July 2, 2011
  • JRuby - Warbler Warbler::Config.new do |config| warble.rb config.dirs = %w(lib) config.includes = FileList["server.rb"] config.war_name = "tarefasWS" endSaturday, July 2, 2011
  • JRuby - Warbler warble warSaturday, July 2, 2011
  • ConclusãoSaturday, July 2, 2011
  • Conclusão - Java como Plataforma Você não precisa mudar de emprego para programar com Ruby ref: http://www.slideshare.net/sifra/jruby-enterprise-20Saturday, July 2, 2011
  • Conclusão - Java como Plataforma Aceite o Java como Plataforma. ref: http://www.slideshare.net/sifra/jruby-enterprise-20Saturday, July 2, 2011
  • Conclusão - Seja PoliglotaSaturday, July 2, 2011
  • Obrigado Hugo Roque Sergio Azevedo Junior hugo.roque@caelum.com.br sergio.junior@caelum.com.br hugolnx.com sagadoprogramador.com.br @hugolnx @sergioazevedoSaturday, July 2, 2011