1 / 35

Groovy vs. JRuby

Groovy vs. JRuby. Rod Cope, CTO & Founder OpenLogic, Inc. Goal. Learn which is best for you if you only have time to learn one scripting language: Groovy or JRuby. Introduction. Rod Cope CTO & Founder of OpenLogic 25 years of software development experience

charlene
Download Presentation

Groovy vs. JRuby

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc.

  2. Goal Learn which is best for you if you only have time to learn one scripting language: Groovy or JRuby

  3. Introduction • Rod Cope • CTO & Founder of OpenLogic • 25 years of software development experience • IBM Global Services, Anthem, Ericsson, many more • OpenLogic, Inc. • SLA support, security updates, and indemnification for over 400 Open Source packages (including Groovy and JRuby) • Dozens of Fortune 500 customers • OSS Census (osscensus.org) • Global, community effort to catalog use of open source • JRuby client

  4. Agenda • Code Samples • Basic Features • Advanced Java Integration • Groovy JDK vs. JRuby/Ruby Libraries • Advanced Features • Demo • Conclusion

  5. Sample: Java and Groovy! public class Filter { public static void main( String[] args ) { List list = new ArrayList(); list.add("Rod"); list.add("Neeta"); list.add("Eric"); list.add("Missy"); Filter filter = new Filter(); List shorts = filter.filterLongerThan(list, 4); System.out.println(shorts.size()); Iterator iter = shorts.iterator(); while (iter.hasNext()) { System.out.println(iter.next()); }} public List filterLongerThan(List list, int length) { List result = new ArrayList(); Iterator iter = list.iterator(); while (iter.hasNext()) { String item = (String) iter.next(); if (item.length() <= length) { result.add(item); } } return result;} }

  6. Groovy! list = ["Rod", "Neeta", "Eric", "Missy"] shorts = list.findAll { name -> name.size() <= 4 } println shorts.size shorts.each { name -> println name } -> 2 -> Rod Eric JRuby! list = ["Rod", "Neeta", "Eric", "Missy"] shorts = list.find_all { |name| name.size <= 4 } puts shorts.size shorts.each { |name| puts name } -> 2 -> Rod Eric

  7. Agenda • Code Samples • Basic Features • Advanced Java Integration • Groovy JDK vs. JRuby/Ruby Libraries • Advanced Features • Demo • Conclusion

  8. Basic Features: Background • Groovy • Started in 2003 by James Strachan and Bob McWhirter • Now led by Guillaume Laforge • Dynamic, object-oriented scripting language for the JVM • Features of Ruby, Python, and Smalltalk • License: Apache 2.0 • JRuby • Started in 2001 by Jan Arne Petersen • Now led by Charles Nutter, Thomas Enebo, Ola Bini, and Nick Sieger • Fast Ruby interpreter and JIT/AOT compiler written in Java • Tight, bi-directional Java integration • License: CPL, GPL, or LGPL

  9. Basic Feature Comparison

  10. Basic Feature Comparison (cont.)

  11. Agenda • Code Samples • Basic Features • Advanced Java Integration • Groovy JDK vs. JRuby/Ruby Libraries • Advanced Features • Demo • Conclusion

  12. Advanced Java Integration • Goal: Use the JScience library (written in Java) • Java usage: Amounta1=Amount.valueOf(3,KILO(GRAM)); Amounta2=Amount.valueOf("2kg"); Amountsum=a1.plus(a2); • Desired usage: a1 = 3.kg a2 = 2.kg sum = a1 + a2

  13. JScience Usage: JRuby Solution # sample units puts 2.kg # 2 kg puts 3.m # 3 m puts 4.5.in # (4.5 +/- 4.4E-16) in include Java require 'jscience.jar' Unit = javax.measure.unit.Unit Amount = org.jscience.physics.amount.Amount class Numeric def method_missing(sym) Amount.valueOf(self, Unit.valueOf(sym.to_s)) end end

  14. JScience Usage: Groovy Solution // sample units println 2.kg // 2 kg println 3.m // 3 m println 4.5.in // (4.5 +/- 4.4E-16) in import javax.measure.unit.* import org.jscience.physics.amount.* // Let ExpandoMetaClass traverse class hierarchies // so properties added to Number are available in // Integer or BigDecimal, etc. ExpandoMetaClass.enableGlobally() Number.metaClass.getProperty = { String symbol -> Amount.valueOf(delegate, Unit.valueOf(symbol)) }

  15. JScience Usage: JRuby Solution (cont.) 18.kg * 2 # 36 kg 1800000.kg / 3 # 600000 kg 1.kg * 2 + 3.kg / 4 # (2.75 +/- 2.2E-16) kg 32.cm + 170.m + 1.km # 117032 cm 121.min – 1.h – 60.s # 60 min 10.m**2 - 32.8.ft**2 # (0.05119344640006 +/- 5.0E-14) m2 -3.h # -3 h 3.h < 4.h # true

  16. JScience Usage: JRuby Solution (cont.) class Amount def *(other) if other.instance_of?(Amount) self.times(other) else self.times(Amount.valueOf(other, Unit::ONE)) end end def +(other) if other.instance_of?(Amount) self.plus(other) else self.plus(Amount.valueOf(other, Unit::ONE)) end end ... end

  17. JScience Usage: JRuby Solution (cont.) [Fixnum,Float].each do |c| c.class_eval do alias original_times * alias original_plus + ... def *(other) if other.instance_of?(Amount) other.times(Amount.valueOf(self, Unit::ONE)) else original_times(other) end end ... end end

  18. JScience Usage: Groovy Solution (cont.) 18.kg * 2 // 36 kg 1800000.kg / 3 // 600000 kg 1.kg * 2 + 3.kg / 4 // (2.75 +/- 2.2E-16) kg 32.cm + 170.m + 1.km // 117032 cm 121.min – 1.h – 60.s // 60 min 10.m**2 - 32.8.ft**2 // (0.05119344640006 +/- 5.0E-14) m2 -3.h // -3 h 3.h < 4.h // true

  19. JScience Usage: Groovy Solution (cont.) Amount.metaClass.multiply = { Number factor -> delegate.times(factor) } Number.metaClass.multiply = { Amount amount -> amount.times(delegate) } Number.metaClass.div = { Amount amount -> amount.inverse().times(delegate) } Amount.metaClass.div = { Number factor -> delegate.divide(factor) } Amount.metaClass.div = { Amount factor -> delegate.divide(factor) } Amount.metaClass.power = { Number factor -> delegate.pow(factor) } Amount.metaClass.negative = { delegate.opposite() }

  20. JScience Integration: Groovy vs. JRuby • Suitability for the task: Tie • Ease of setup: Groovy (slight edge) • Ease of use: Tie • Performance: Groovy • 3x faster in my benchmark (was 5x faster last month) • Partially due to extra type conversions required in JRuby • Being addressed by JRuby team

  21. Agenda • Code Samples • Basic Features • Advanced Java Integration • Groovy JDK vs. JRuby/Ruby Libraries • Advanced Features • Demo • Conclusion

  22. Groovy JDK vs. JRuby/Ruby Libraries • Groovy JDK • Adds lots of utility methods to String, File, Collection, etc. • Heavily inspired by Ruby • Robust and easy to add new ones String.metaClass.alphabetical = { (delegate.toCharArray() as List).sort().join() } "scripts".alphabetical() // ciprsst • JRuby/Ruby Libraries • JRuby can use both the JDK release and all of Ruby's libraries • Very robust and easy to add new ones def String.alphabetical self.split("").sort.join end "scripts".alphabetical # ciprsst

  23. Agenda • Code Samples • Basic Features • Advanced Java Integration • Groovy JDK vs. JRuby/Ruby Libraries • Advanced Features • Demo • Conclusion

  24. Advanced Features • Groovy: Expando rod = new Expando(name: 'Rod', age: 37) rod.drinkWater = { num -> num.times { println "yum!" } } rod.age // 37 rod.drinkWater(2) // yum! // yum! • JRuby: OpenStruct require 'ostruct' rod = OpenStruct.new(:name => 'Rod', :age => 37) def rod.drinkWater(num) num.times { println "yum!" } } end rod.age # 37 rod.drinkWater(2) # yum! # yum!

  25. Advanced Features: Groovy package com.openlogic class Company { String name Address address List employees = [] } class Address { String street int zip String state } class Employee { String name int employeeId Address address Company company }

  26. Advanced Features: Groovy def builder = new ObjectGraphBuilder( classNameResolver: "com.openlogic") def company = builder.company(name: 'OpenLogic') { address(id:'a1', street:'Elm', zip:80021, state:'CO') employee(name: 'Rod', employeeId: 1) { address(refId: 'a1') } employee(name: 'Eric', employeeId: 2) { address(refId: 'a1') } } println company.employees.size() // 2 println company.address.zip // 80021 company.employees.each { // Rod, 1 println "${it.name}, ${it.employeeId}" // Eric, 2 } println company.employees[1].address.street // Elm

  27. Advanced Features: JRuby class Order < ActiveRecord::Base belongs_to :user has_many :transactions validates_presence_of :quantity, :price validates_numericality_of :quantity, :integer_only => true validates_inclusion_of :quantity, :in => 1..1_000_000, :message => "should be between 1 and 1,000,000" def cancelled? transactions.empty? && price < 0 end end

  28. Advanced Features: JRuby • Low level file operations • File class: chmod, setuid?, symlink?, ln_s, etc. • REXML require "rexml/document"; include REXML addrbook = Document.new(File.new("address.xml")).root puts addrbook.elements["//person[2]/address"] .attributes["city"] • Code can run under both JRuby/JVM machine and C-based Ruby begin require 'java' JAVA = true rescue LoadError JAVA = false end if JAVA ...

  29. Agenda • Code Samples • Basic Features • Advanced Java Integration • Groovy JDK vs. JRuby/Ruby Libraries • Advanced Features • Demo • Conclusion

  30. Groovy and JRuby Demo

  31. Demo code • Groovy • Download xmlrpc module • import groovy.net.xmlrpc.* • server = new XMLRPCServer() • server.multiply = { it * 3 } • server.startServer(new java.net.ServerSocket(9047)) • server.stopServer() // later • JRuby • require 'xmlrpc/client' • server = XMLRPC::Client.new2("http://localhost:9047") • server.call("multiply", 2) • def server.method_missing(sym, *args) • self.call(sym.to_s, *args) • end • server.multiply 7 • server.multiply "cool "

  32. Agenda • Code Samples • Basic Features • Advanced Java Integration • Groovy JDK vs. JRuby/Ruby Libraries • Advanced Features • Demo • Conclusion

  33. Conclusion • Groovy • Seamless fit with existing Java code • Performance is good and improving • Best suited for tight and/or heavy Java code integration • Grails • JRuby • Java code integration is good, but needs some work • Performance is good and improving all the time • Best suited for general scripting and light Java code integration • Rails

  34. For More Information • Groovy • http://groovy.codehaus.org • Article on JScience integration by Guillaume Laforge:http://groovy.dzone.com/news/domain-specific-language-unit- • Grailshttp://grails.codehaus.org/ • JRuby • http://jruby.codehaus.org • Railshttp://rubyonrails.org • Both • Great comparison of Java, Groovy, and JRuby syntax:http://blogs.sun.com/sundararajan/entry/java_groovy_and_j_ruby

  35. Q & A Any questions for Rod? Image licensed from BigStockPhoto.com

More Related