Ruby Language Goodies For Java Developers

If you are new to the Ruby programing language you might not be familiar with some of the short semantic sugar or language goodies that Ruby provides. I think that for most of the hard core Java developers the code samples that will be provided here will be novel but Perl hackers will not be impressed. So as an aid to all my fellow Java developers I will try to compare and contrast Ruby code with Java. To get started lets set three values to three variables in one line of Ruby code:

var1, var2, var3 = 'one', 'two', 'three'

You can’t do this in Java. The best you can do in Java is set three variables with the same value, which Ruby also supports, like this:

var1 = var2 = var3 = 'same value'

Methods
In Ruby, you can initialize default values to method parameters. Here is an example of a method with three parameters initialized to a numeral literal, empty list, and empty hash.

def my_method(parama = 1, paramb = [], paramc = {})
  # method implementation here
end

To invoke my_method you can do so with any of the following lines of code:

my_method
my_method()
my_method(2)
my_method(2, [:abc, :def])
my_method(2, [:abc, :def], :abc => 'abc', :def => 'def')
my_method 2, [:abc, :def], :abc => 'abc', :def => 'def'
my_method 2, [:abc, :def], {:abc => 'abc', :def => 'def'}

This is not method overloading as seen in Java. All of the above method calls invoke the same block of code, the same method implementation. In Java you would define overload the method by defining a separate implementation for each method signature.

Java 1.5 recently introduced variable length arguments, varargs. You could have done this in Ruby years back. To define a Ruby method with variable number of parameters you can do the following:

def my_vararg_method *params
  # params is an array
end

To invoke my_vararg_method you can do so with any of the following lines of code:

my_varargs_method # params is empty
my_varargs_method 'string', :symbol, {} # params = ['string', :symbol, {}]

At this time I invite you to notice that parentheses, like semi-colons, are not required.

Objects
In Java you have two types of data, objects and native. An int is completely different than an instance of Integer and depending on the situation you had to constantly convert one to the other. In Ruby everything is an object, and when I say everything I mean everything including the nil value. The nil value is Ruby’s equivalent to the Java null keyword. In Ruby you can do the following:

1.nil? # false
nil.nil? # true
1.3.class # Float
1.is_a? Float # false
'0'.to_i + 1 # 1
Float.class # Class

And because in Ruby everything is an object you don’t need a autoboxing hack to use the literal 1 as a key in a hash.

hash = {1 => 'one', 2 => 'two', 3 => 'three'}

Lists
Another convenient language goodie available in Ruby is the array initializer. If you want to construct an array of string values without white spaces in them you can quickly do so with the following statement:

list = %w(female male) # list = ["female", "male"]

If you need a whitespace inside a word just escape it with the backslash (\). Now If you want to define an array with the first 10 digits you can easily do so with ranges. Here is an example of how to construct an array composed of the numbers between 0 to 9, inclusive.

nums = (0 .. 9).to_a

Here is how to iterate through each letter in the alphabet using ranges.

('A' .. 'Z').each { |char| puts char }

If you want to loop over an array you will need a range from 0 to the array size, exclusive. To create an exclusive range use the … operator as in the following:

arr =  get_list # some array
(0 ... arr.size).each { |index| print arr[index] }

Control
To wrap let me walk through some Ruby control constructs. In addition to the control construct that Java developers are familiar with Ruby provides a unless and until. The ‘unless condition’ is equivalent to ‘if not condition.’ The ‘until condition’ is equivalent to ‘while not condition.’ Here is a trivial example of the the unless construct.

unless item.invalid?
  print item.to_s
end

Ruby also provides a shortcut for the above code in the form of conditional modifiers.

print item.to_s unless item.invalid?

In both of the above code snippets the item will only be printed if the item is in a valid state. You can use if, unless, while, and until as conditional modifier.

As a bonus, let me state where Ruby is lacking. The Ruby language does not support the — and ++ operator. The best you can do in Ruby is use the next method available to the Integer class.