Java, Groovy and (J)Ruby - Part 2

This is continuation of my earlier post.

What this is not?
  • not a detailed language comparison exercise - that helps you in selecting one for development!
  • not a complete overview. Not every feature is covered. Hey, book writers have to make money ;-) Also, commenters need to post something ;-)
Then, what exactly is this?
  • Notes of a Java programmer who is learning Groovy and JRuby.
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

Comments:

[Trackback] a. sundararajan continued his comparision chart mentioned earlier, although he insists that it’s not complete and he is still learning the languages depicted. anyway, i think it gives you a nice overview of differences and what these languages ha...

Posted by stotti.blog() on September 19, 2006 at 11:24 AM IST #

Hey, great work! I've been excited about the scripting languages for java and the jvm and am delighted to see your work.

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 03:03 PM IST #

Hi Owen Densmore: I need to learn Jython/Python -- I know a bit but not much. May be, one of these days.. BTW, there is a JSR-223 script engine for Java (as part of the scripting.dev.java.net project). Using this script engine, you can "eval" Java code from a string or a java.io.Reader. There is no real magic - behind the scene javac's compiler API (JSR 199) is used to compile the java code into a byte array and then a classloader is used to load the resultant .class bytes.

Posted by A. Sundararajan on September 19, 2006 at 03:12 PM IST #

Hi Sundar, great work doing this compilation of info. Some of Groovy's "interesting stuff" I discovered through your blog, kep it up! =)

Posted by Andres Almiray on September 19, 2006 at 09:20 PM IST #

One thing I've had difficulties with using the "agile" jvm languages (groovy, jython, jruby, etc) is whether or not you can build applets with them.

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 02:16 AM IST #

Post a Comment:
Comments are closed for this entry.
About

sundararajan

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks
Links

No bookmarks in folder

Blogroll

No bookmarks in folder

News

No bookmarks in folder