groovy vs. jruby rod cope, cto & founder openlogic, inc

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

Upload: ralph-holland

Post on 28-Dec-2015

222 views

Category:

Documents


3 download

TRANSCRIPT

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

Groovy vs. JRubyRod Cope, CTO & FounderOpenLogic, Inc.

Page 2: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

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

Goal

Page 3: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Introduction

Rod CopeCTO & Founder of OpenLogic25 years of software development experienceIBM 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 sourceJRuby client

Page 4: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Agenda

Code Samples

Basic Features

Advanced Java Integration

Groovy JDK vs. JRuby/Ruby Libraries

Advanced Features

Demo

Conclusion

Page 5: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Sample: Javapublic 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;}

}

and Groovy!

Page 6: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Groovy!

list = ["Rod", "Neeta", "Eric", "Missy"]shorts = list.find_all { |name| name.size <= 4 }puts shorts.sizeshorts.each { |name| puts name }

-> 2 -> Rod Eric

JRuby!

list = ["Rod", "Neeta", "Eric", "Missy"]shorts = list.findAll { name -> name.size() <= 4 }println shorts.sizeshorts.each { name -> println name }

-> 2 -> Rod Eric

Page 7: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Agenda

Code Samples

Basic Features

Advanced Java Integration

Groovy JDK vs. JRuby/Ruby Libraries

Advanced Features

Demo

Conclusion

Page 8: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Basic Features: Background

GroovyStarted in 2003 by James Strachan and Bob McWhirterNow led by Guillaume LaforgeDynamic, object-oriented scripting language for the JVMFeatures of Ruby, Python, and SmalltalkLicense: Apache 2.0

JRubyStarted in 2001 by Jan Arne PetersenNow led by Charles Nutter, Thomas Enebo, Ola Bini, and Nick SiegerFast Ruby interpreter and JIT/AOT compiler written in JavaTight, bi-directional Java integrationLicense: CPL, GPL, or LGPL

Page 9: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Basic Feature ComparisonFeature Groovy JRuby

Optionals int a = 2

def str = "Hello"

a = 2

str = "hello"

Native data structure syntax

def list = ["Rod",3,new Date()]

def map = ["Neeta": 33, "Eric" : 35]

list = ["Rod", 3, Time.new]

map = { "Neeta" => 33, "Eric" => 35 }

Closures/Blocks

map.each { name, age -> println "${name} is ${age}" }

map.each { |name, age| puts "#{name} is #{age}"}

Regex re = /na.*/

println "name" ==~ re //true

println re ==~ "name" //false

re = /na.*/

puts "name" =~ re # 0

puts re =~ "name" # 0

Operator Overload

def list = [1,2,3] + [4,5,6]

println list.join() // 123456

list = [1,2,3] + [4,5,6]

puts list.join # 123456

Friendly println [1,2,3].size() // 3

println "dog".size() // 3

puts [1,2,3].size # 3

puts "dog".size # 3

Page 10: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Basic Feature Comparison (cont.)

Feature Groovy JRuby

Read a file println new File('file.txt').text

puts File.new('file.txt').read

Interactive Shell

groovysh – good, but not very robust jirb – very strong

Duck Typing Don't need to implement an interface or use types – they're optional

a = 1000 // Integer

a = 1000000000000 // Long

a = 1000000000000000000000

// BigInteger

a = 1000 // 1000

a = a * a // 1000000

a = a * a // -727379968

No interfaces or types, just objects that receive messages

a = 1000 // Fixnum

a = 10000000000000 // Fixnum

a = 1000000000000000000000

// Bignum

a = 1000 // 1000

a = a * a // 1000000

a = a * a // 1000000000000

a = a * a // 1000...000000

...

Page 11: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Agenda

Code Samples

Basic Features

Advanced Java Integration

Groovy JDK vs. JRuby/Ruby Libraries

Advanced Features

Demo

Conclusion

Page 12: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Advanced Java Integration

Goal: Use the JScience library (written in Java)

Java usage:Amount a1 = Amount.valueOf(3, KILO(GRAM));  

Amount a2 = Amount.valueOf("2 kg");  

Amount sum = a1.plus(a2); 

Desired usage:a1 = 3.kg

a2 = 2.kg

sum = a1 + a2

Page 13: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

JScience Usage: JRuby Solution# sample unitsputs 2.kg # 2 kgputs 3.m # 3 mputs 4.5.in # (4.5 +/- 4.4E-16) in

include Javarequire 'jscience.jar'Unit = javax.measure.unit.UnitAmount = org.jscience.physics.amount.Amount

class Numeric def method_missing(sym) Amount.valueOf(self, Unit.valueOf(sym.to_s)) endend

Page 14: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

JScience Usage: Groovy Solution

// sample unitsprintln 2.kg // 2 kgprintln 3.m // 3 mprintln 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)) }

Page 15: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

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

Page 16: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

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

Page 17: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

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 ... endend

Page 18: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

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

Page 19: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

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() }

Page 20: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

JScience Integration: Groovy vs. JRuby

Suitability for the task: Tie

Ease of setup: Groovy (slight edge)

Ease of use: Tie

Performance: Groovy3x faster in my benchmark (was 5x faster last month)Partially due to extra type conversions required in JRubyBeing addressed by JRuby team

Page 21: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Agenda

Code Samples

Basic Features

Advanced Java Integration

Groovy JDK vs. JRuby/Ruby Libraries

Advanced Features

Demo

Conclusion

Page 22: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Groovy JDK vs. JRuby/Ruby Libraries

Groovy JDKAdds lots of utility methods to String, File, Collection, etc.Heavily inspired by RubyRobust and easy to add new onesString.metaClass.alphabetical = {

(delegate.toCharArray() as List).sort().join() } "scripts".alphabetical() // ciprsst

JRuby/Ruby LibrariesJRuby can use both the JDK release and all of Ruby's librariesVery robust and easy to add new onesdef String.alphabetical

self.split("").sort.join end "scripts".alphabetical # ciprsst

Page 23: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Agenda

Code Samples

Basic Features

Advanced Java Integration

Groovy JDK vs. JRuby/Ruby Libraries

Advanced Features

Demo

Conclusion

Page 24: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

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!

Page 25: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

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 }

Page 26: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Advanced Features: Groovydef 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() // 2println company.address.zip // 80021company.employees.each { // Rod, 1 println "${it.name}, ${it.employeeId}" // Eric, 2}println company.employees[1].address.street // Elm

Page 27: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

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 endend

Page 28: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Advanced Features: JRuby

Low level file operationsFile class: chmod, setuid?, symlink?, ln_s, etc.

REXMLrequire "rexml/document"; include REXMLaddrbook = Document.new(File.new("address.xml")).rootputs addrbook.elements["//person[2]/address"] .attributes["city"]

Code can run under both JRuby/JVM machine and C-based Rubybegin require 'java' JAVA = truerescue LoadError JAVA = falseendif JAVA ...

Page 29: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Agenda

Code Samples

Basic Features

Advanced Java Integration

Groovy JDK vs. JRuby/Ruby Libraries

Advanced Features

Demo

Conclusion

Page 30: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Groovy and JRuby Demo

Page 31: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Demo code

GroovyDownload xmlrpc moduleimport groovy.net.xmlrpc.*server = new XMLRPCServer()server.multiply = { it * 3 }server.startServer(new java.net.ServerSocket(9047))server.stopServer() // later

JRubyrequire '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)endserver.multiply 7server.multiply "cool "

Page 32: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Agenda

Code Samples

Basic Features

Advanced Java Integration

Groovy JDK vs. JRuby/Ruby Libraries

Advanced Features

Demo

Conclusion

Page 33: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Conclusion

GroovySeamless fit with existing Java codePerformance is good and improvingBest suited for tight and/or heavy Java code integrationGrails

JRubyJava code integration is good, but needs some workPerformance is good and improving all the timeBest suited for general scripting and light Java code integrationRails

Page 34: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

For More Information

Groovyhttp://groovy.codehaus.orgArticle on JScience integration by Guillaume Laforge:http://groovy.dzone.com/news/domain-specific-language-unit- Grailshttp://grails.codehaus.org/

JRubyhttp://jruby.codehaus.orgRailshttp://rubyonrails.org

BothGreat comparison of Java, Groovy, and JRuby syntax:http://blogs.sun.com/sundararajan/entry/java_groovy_and_j_ruby

Page 35: Groovy vs. JRuby Rod Cope, CTO & Founder OpenLogic, Inc

OpenLogic Company Confidential

Q & A

Any questions for Rod?

Image licensed from BigStockPhoto.com