Saturday, May 9, 2009

JRuby Supports Java and Ruby Method Names Conventions

Jeff Cohen's blog post Ruby 101: Naming Conventions does a nice job of covering conventions associated with the Ruby programming language. I like how he specifically writes to Java developers and .NET developers to call out differences in conventions from those respective worlds from what is conventional in Ruby.

Because JRuby supports use of Java classes within Ruby code running on the JVM, it is not surprising that differences of convention are more likely to be noticed in JRuby development. One area in which Java and Ruby differ in convention is the naming of methods. JRuby conveniently allows Ruby code calling Java classes to call methods on those Java classes using either a traditional Java method naming convention (with or without parentheses) or using Ruby-friendly syntax (all lowercase letters with underscores separating the different words).

The following simple JRuby script uses the Java System.getProperties() method to get all of the defined system properties. It uses both a traditional Java method name convention and the Ruby-centric equivalent get_properties. Note that I did not need to do anything special to get this support.


# The purpose of this JRuby script is to demonstrate that JRuby supports
# Ruby-consistent method name syntax even on standard Java classes.

# Will be calling Java classes from this JRuby script
include Java

# Need to import System to avoid "uninitialized constant System (NameError)"
import java.lang.System

separator = "=================================================================="

# Java-style:
# The first access of System.getProperties is implemented as would be done in
# 'traditional' Java. The parentheses are not required on getProperties()
# call because it has no parameters passed to it, but the parentheses are
# retained here as more conducive to Java style.
puts separator
puts "CLASSICAL JAVA"
puts separator
puts "#{System.getProperties()}"

# Ruby-style:
# Ruby convention tends to favor separating multiple words in method names
# with underscores rather than with uppercase first letters as is Java's
# convention.
puts separator
puts "RUBY-ED JAVA"
puts separator
puts "#{System.get_properties}"



When the above script is run, both calls to System.getProperties() work exactly the same.

The example so far called a Java method that did not accept any parameters. However, the same support for Ruby method naming convention, Java method naming convention, or some combination of these is supported with methods that accept parameters. The two examples printed to standard output from the next code listing display exactly the same information based on a call to System.getProperty(String).


# Java-style with parameters:
# Can use traditional Java style name and can use or not use parentheses.
# Truly traditional Java-style would employ parentheses, but I wanted to show
# that they are not necessary in JRuby even when using the camel case method
# naming convention.
puts separator
puts "Java Version (Java-style): #{System.getProperty 'java.version'}"
puts separator

# Ruby-style with parameters:
# I could have added parentheses here, but they are only necessary if the
# object returned from the method call needs to have something access on it
# in the same line, which I am not doing here.
puts separator
puts "Java Version (Ruby-style): #{System.get_property 'java.version'}"
puts separator


In this case, I intentionally left the parentheses out of the example that would have otherwise been compliant with Java method naming convention.

I have found it generally best to try to accommodate the conventions of a particular programming language because of the many benefits gained from doing so (improved ability to read and maintain others' code, improved reflection capabilities, improved opportunities for convention over configuration or configuration by exception, and so forth). However, it can be a little less clear sometimes with JRuby, particularly when calling Java classes and methods.

Outside of personal taste, there is nothing better or worse about Java's or Ruby's method naming conventions; rather, they are just different. I have a very slight preference for using the syntax that is compliant with Ruby convention in JRuby code because most of the surrounding JRuby code is Ruby and consistency is often a highly desirable goal. However, on the list of matters of personal tastes and preferences, this ranks way, way down there. It is far more important to me that I can leverage the benefits of Java and the JVM with the benefits of Ruby.

1 comment:

Antonio said...

The other convention that would be awesome would be handling .property= and .property as equivalents to .getProperty and .setProperty where possible. QtRuby does that very well, and it goes a long way toward making the usage look very Ruby-like.