Download Groovy vs. JRuby

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
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
OpenLogic Company Confidential
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
OpenLogic Company Confidential
Agenda
Code Samples
Basic Features
Advanced Java Integration
Groovy JDK vs. JRuby/Ruby Libraries
Advanced Features
Demo
Conclusion
OpenLogic Company Confidential
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;
}
OpenLogic Company Confidential
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
OpenLogic Company Confidential
Agenda
Code Samples
Basic Features
Advanced Java Integration
Groovy JDK vs. JRuby/Ruby Libraries
Advanced Features
Demo
Conclusion
OpenLogic Company Confidential
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
OpenLogic Company Confidential
Basic Feature Comparison
Feature
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
println re ==~ "name"
re = /na.*/
puts "name" =~ re
puts re =~ "name"
//true
//false
# 0
# 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()
println "dog".size()
puts [1,2,3].size
puts "dog".size
// 3
// 3
OpenLogic Company Confidential
# 3
# 3
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
No interfaces or types, just objects that receive
messages
a = 1000
// Integer
a = 1000000000000 // Long
a = 1000000000000000000000
// BigInteger
a = 1000
// 1000
a = a * a
// 1000000
a = a * a
// -727379968
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
...
OpenLogic Company Confidential
Agenda
Code Samples
Basic Features
Advanced Java Integration
Groovy JDK vs. JRuby/Ruby Libraries
Advanced Features
Demo
Conclusion
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
OpenLogic Company Confidential
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
OpenLogic Company Confidential
JScience Usage: Groovy Solution
// sample units
println 2.kg
println 3.m
println 4.5.in
// 2 kg
// 3 m
// (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)) }
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
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
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
...
end
end
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
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() }
OpenLogic Company Confidential
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
OpenLogic Company Confidential
Agenda
Code Samples
Basic Features
Advanced Java Integration
Groovy JDK vs. JRuby/Ruby Libraries
Advanced Features
Demo
Conclusion
OpenLogic Company Confidential
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
OpenLogic Company Confidential
Agenda
Code Samples
Basic Features
Advanced Java Integration
Groovy JDK vs. JRuby/Ruby Libraries
Advanced Features
Demo
Conclusion
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!
JRuby: OpenStruct
// yum!
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!
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
}
OpenLogic Company Confidential
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()
println company.address.zip
company.employees.each {
println "${it.name}, ${it.employeeId}"
}
println company.employees[1].address.street
OpenLogic Company Confidential
//
//
//
//
2
80021
Rod, 1
Eric, 2
// Elm
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
OpenLogic Company Confidential
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
...
OpenLogic Company Confidential
Agenda
Code Samples
Basic Features
Advanced Java Integration
Groovy JDK vs. JRuby/Ruby Libraries
Advanced Features
Demo
Conclusion
OpenLogic Company Confidential
Groovy and JRuby Demo
OpenLogic Company Confidential
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 "
OpenLogic Company Confidential
Agenda
Code Samples
Basic Features
Advanced Java Integration
Groovy JDK vs. JRuby/Ruby Libraries
Advanced Features
Demo
Conclusion
OpenLogic Company Confidential
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
OpenLogic Company Confidential
For More Information
Groovy
http://groovy.codehaus.org
Article on JScience integration by Guillaume Laforge:
http://groovy.dzone.com/news/domain-specific-language-unitGrails
http://grails.codehaus.org/
JRuby
http://jruby.codehaus.org
Rails
http://rubyonrails.org
Both
Great comparison of Java, Groovy, and JRuby syntax:
http://blogs.sun.com/sundararajan/entry/java_groovy_and_j_ruby
OpenLogic Company Confidential
Q&A
Any questions for Rod?
Image licensed from BigStockPhoto.com
OpenLogic Company Confidential
Related documents