So let's start by looking at the advantages that each language has over the other.
Ruby advantages
Everything is an object
In Ruby everything is an object, even primitive types and classes. The fact that a class is an object makes it much easier to write unit tests because it allows you to mock them and to create stubs for class methods as well.
In Java, instead, you cannot mock static methods. This makes it difficult to test units that make use of them. You end up implementing instance methods even for functionalities that do not use any information about the object's state but just to facilitate testing.
Modules
Modules allow for a class to include functionalities without the need to extend any parent class. This makes it easy to reuse cross-cutting concerns like logging, security, transaction management and so on.
To achieve the same in Java you need to use delegation which can require a lot of repetitive code.
Module are sometimes abused, though, like Ryan Bates points out in this gist.
Blocks of code
This is one of the main attractions for newcomers to Ruby. Blocks of code allow for a very concise syntax to implement the Template Method Pattern.
Java requires the definition of an interface and multiple classes implementing it, this again results in more verbosity.
Duck typing and syntactic sugars
Both features make the code extremely compact and readable: no need for type definition or type casting, no semicolons at the end of the line, no parentheses for method invocations, operators overload, getters/setters automatically available for all instance variables and many, many more.
Ruby code is incredibly expressive and easy to read, many say indeed that "Ruby speaks English". To understand the concept it is enough to read some tests written using RSpec, which I consider one of the best library I ever used.
On the other hand, Java code is verbose and it can require multiple lines of code for stuff which you could get done in a single line in Ruby.
No compilation required
The thing that annoys me most while working on a Java web project is that every time I change something , even if it is just a Javascript or CSS file, I need to re-compile and re-deploy. This is not the case with Ruby resulting in a boost in productivity.
Java advantages
Performance
Performance can be the single reason to prefer Java over Ruby.
In web applications, though, 90% of the time is spent in the database, in requests to external systems and not in the language itself. If your web app is slow and you decide to replace Ruby with Java, you will probably not achieve much improvement.
On the other hand, if you are working on an application making intensive calculations, than Java outperforms Ruby. The following benchmarks executed on a x64 Intel quad-core running on Ubuntu gives you an idea of the difference in performance between the two languages: http://benchmarksgame.alioth.debian.org/u64q/which-programs-are-fastest.php.
Multi-threading and concurrency
The results from the previous benchmark derive also from the fact that Ruby, or at least the MRI implementation, does not support threads. JRuby and Rubinius do support threads but I think 95+% of Ruby production environments are based on MRI.
In a web application, it is necessary to launch different processes in order to be able to handle multiple requests which is something that does not scale very well.
Doing parallel computations is very problematic without threads. If using separate processes, the only way to let them share data is through a database, a file or some other external resource whose access speed is obviously way slower than memory.
Interfaces
Interfaces are a very simple and clear way to define the contract between a piece of software and the external world. Unfortunately, many people abuse them and create interfaces for every single class they write.
However, when used properly they do help understanding how a module works and how to use it. Furthermore, interfaces allow to modify a module or to completely replace it in a manner completely transparent to rest of the system.
IDE support
Eclipse, Intellij, Netbeans all make the life of every Java Developer so much easier by refactoring variables, methods, classes. They also let you quickly navigate through the classes and save a lot of keystrokes with auto-completion.
The features I consider the most useful are those for reverse engineering, like showing class hierarchies or methods usage. This can be a life-safer, especially when working on big, old projects, where many contributors were not writing really clean code, just to use an euphemism :)
Because of the extremely dynamic nature of Ruby, IDE cannot help much in this sense and without an extensive test suite it can be really hard to extend or modify an old Ruby project.
Conclusions
I think both Ruby and Java are great. It would be nice if they could somehow blend into one language that combines the best of both worlds. Actually, I think this language already exists!!! I am talking about Scala, of course.Scala combines the flexibility, expressiveness and conciseness of Ruby with the performance, scalability and tools support of Java. Scala takes this even further by being a truly functional language which makes it suitable for concurrent, scalable and fault-tolerant applications.
Companies like Twitter and Linkedin are successfully using it and I believe there prospects a really bright future for this language.
There is also JRuby, you can write lots of stuff in ruby and integrate already existing codebase in java or just write in java code that needs to be optimized :)
ReplyDeleteYes, I indeed mentioned JRuby as well :)
ReplyDelete