|
Feature
|
Java
|
Groovy
|
JRuby
|
|
Default argument
|
Not supported (intentionally!)
|
class Person {
def greet(msg="hello world") {
println(msg);
}
}
p = new Person()
// leave argument, default taken
p.greet()
// argument to override the default
p.greet "Groovy!"
|
class Person
def greet(msg="hello world")
puts msg
end
end
// leave argument, default taken
Person.new.greet
// argument to override the default
Person.new.greet "JRuby!"
|
|
Type for floating point literals
[Thanks to Scott Hickey]
|
double
|
java.math.BigDecimal
|
Float class (representation is Java double)
|
|
enum
|
Java enum guide
|
Not supported (yet?)
|
Not supported.
See also:
* Add enum to Ruby
* Ruby idiom for enum?
|
|
Is everything an object?
|
No, there are primitive types and reference types.
But, with auto boxing/unboxing,
you can use primitives with ease
|
Yes
println 5.class
5.times { println "hello" }
null seems like an object (you can call methods on it).
but (null instanceof Object) is false!
|
Yes
puts 5.class
5.times { puts "hello" }
nil is an object. (nil.kind_of? Object) is true.
|
|
instance of check
|
obj instanceof ClassName
// for exact instance check
// excluding subtype objects
obj.getClass() == ClassName.class
|
Same as Java. In addition, you could compare
MetaClass
as well (which is dynamic and be changed).
obj.metaClass == known_metaClass
|
class Person
end
class Employee < Person
end
e = Employee.new
# kind_of? includes subtypes
# Note: kind_of? is like Java's
# instanceof is_a? is
# synonym for kind_of?
# prints true for both these
puts e.kind_of?(Employee)
puts e.kind_of?(Person)
# Note: instance_of?
# is different from Java's
# instanceof.
# this prints false
puts e.instance_of?(Person)
# this prints true
puts e.instance_of?(Employee)
|
|
Class Literals
|
ClassName.class
java.awt.Frame.class
Person.class
|
Same as Java.
|
Java Trap: just use ClassName for
class literal of ClassName. All the built-in
and user classes have a corresponding global
constant with the same name as the class.
If you say, Person.class that is
different -- that is similar to saying
Person.class.getClass() in Java.
class Person
end
def factory(klass)
obj = klass.new
puts "Created #{obj}"
return obj
end
# To pass Person class, we
# just use Person!
factory Person
|
|
Throwing Exception
|
throw exception;
|
Same as Java - except the throwing method
need not have throws clause - even for checked
exceptions.
|
raise exception
|
|
Printing Stack Trace
|
Thread.dumpStack();
|
Same as Java.
|
caller.join("\n");
def method1
method2
end
def method2
method3
end
def method3
puts caller.join("\n");
end
method1
|
|
Handling "missing method"
|
This can not happen in Java! That's the
point of static type checking.
Either you have to use reflection or
change classes incompatibly behind
javac's back to get this error. In such
cases, you have to catch NoSuchMethodException
or NoSuchMethodError.
|
class Person {
def invokeMethod(String name, args) {
println(name + " called");
}
}
p = new Person();
// no "greet" method, "invokeMethod"
// is called.
p.greet();
Note: There are also more powerful ways to
intercept method dispatching with
MetaClasses in Groovy.
|
class Person
def method_missing(name, *args)
puts name.to_s + " called"
end
end
p = Person.new
# no "greet" method, so "method_missing"
# will be called
p.greet
|
|
Open Classes
|
Static typing is incompatible with this!
|
Not directly supported. But, I think you can
play with use and/or
MetaClasses
to simulate
it.
Using Categories
class Person {
def greet() {
sayHello()
}
}
p = new Person()
class Greeter {
static def sayHello(obj) {
println "hello world"
}
}
use(Greeter) {
p.greet()
}
Note that the above works only within the
use statement. What if you want
to make the change global?
|
class Person
def greet
sayHello
end
end
# again class Person!
# could be defined anywhere.
# declare more methods.
class Person
def sayHello
puts "hello world"
end
end
Person.new.greet
See also:
* Another example: here
* The Open Class Mindset
* Are Ruby's Open Classes a Poor Fit for Large Projects?
|
|
Extending a specific object
|
Not supported. You may think of singleton
instance of an anonymous class. But, that
does not allow you to extend a pre-existing
instance.
|
Changing MetaClass
class Person {
def greet() {
sayHello()
}
}
p = new Person()
def pmc = ProxyMetaClass.
getInstance(Person.class);
class MyInterceptor
implements Interceptor {
def invoke
Object beforeInvoke(Object object,
String name, Object[] args) {
if (name == "sayHello") {
println "hello world"
invoke = false
} else {
invoke = true
}
}
boolean doInvoke() {
return invoke
}
Object afterInvoke(Object obj,
String name, Object[] args,
Object res) {
return null
}
}
pmc.interceptor = new MyInterceptor()
p.metaClass = pmc;
p.greet()
Using Expando
// Expando allows you to add properties
// dynamically. The properties may be
// Closure valued.
class Person extends Expando {
}
p = new Person()
// add a property that is a closure
p.greet = { println "p's hello"}
// call it like a method
p.greet()
p2 = new Person()
p2.greet = { println "p2's hello" }
p2.greet()
|
class Person
def greet
puts "hello"
end
end
p1 = Person.new
p2 = Person.new
# change p2's greet method
def p2.greet
puts "p2's hello"
end
p1.greet
p2.greet
# extend "p2" to override
# and may be even add
# more methods
class <<p2
def greet
puts "p2's changed hello"
end
def goodbye
puts "p2's goodbye"
end
end
p2.greet
p2.goodbye
|
Posted by stotti.blog() on September 19, 2006 at 06:24 PM IST #
One language I've been impressed by is Jython, although the team is quite small. The community is quite active, and the 2.2.a release includes very important upgrades.
Any chance you could include Jython in your comparisons?
BTW: You mention in an earlier post that Java can "eval" expressions. Sounds interesting .. but how?!
Thanks
-- Owen
Owen Densmore 505-988-3787 http://backspaces.net
Redfish Group: 505-995-0206 http://redfish.com http://friam.org/
Posted by Owen Densmore on September 19, 2006 at 10:03 PM IST #
Posted by A. Sundararajan on September 19, 2006 at 10:12 PM IST #
Posted by Andres Almiray on September 20, 2006 at 04:20 AM IST #
I think Groovy and JRuby no, but Jython yes .. as long as you don't use eval() or other dynamic features.
So I recommend yet another row in your matrix: "Applets possible?"
-- Owen
Posted by Owen Densmore on September 21, 2006 at 09:16 AM IST #