JRuby
Découverte de JRuby
JRuby est un interpréteur Ruby écrit en Java à l’instar de Jython pour Python. Cet article a pour but de vous faire découvrir JRuby et de montrer ces limitations.
JRuby est très simple à utiliser. Pour le prouver nous allons réaliser un simple hello world. Tout d’abord vous devez avoir un environnement Java et récupérer l’archive jruby.jar. Dans les exemples de l’article on supposera que jruby.jar est dans le répertoire courant.
Voici notre hello world.
puts 'Hello world !'
Il s’exécute à l’aide de la commande suivante.
java -jar jruby.jar hello1.rb
On peut même utiliser des classes Java dans le code Ruby. Voici une autre version du hello world avec la classe System cette fois-ci.
require 'java'
include_class 'java.lang.System'
System.out.println('Hello world !')
Nous allons aller un peu plus loin en créant une fenêtre Swing en Ruby.
require 'java'
include_class 'javax.swing.JFrame'
include_class 'javax.swing.JLabel'
include_class 'java.lang.Runnable'
include_class 'java.awt.EventQueue'
class App < Runnable
def run
frame = JFrame.new('JRuby & Swing');
frame.setSize(320, 200)
frame.getContentPane.add(JLabel.new('A Ruby label in Swing !'))
frame.setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
frame.setVisible(true)
end
end
EventQueue.invokeLater(App.new)
Ce code crée une fenêtre, lui attribue une taille, rajoute un label, définit l’opération à la fermeture de la fenêtre et la rend visible.
Puis on exécute toujours le script avec la même commande.
java -jar jruby.jar swing1.rb
De ce constat on peut se dire que l’on va pouvoir créer des applications en couplant ces deux langages aisément. Vérifions cela en créant notre propre composant graphique. On va personnaliser Jlabel pour en faire un Rlabel. Pour cette tâche il est simplement nécessaire d’hériter Jlabel et de redéfinir la méthode paint où l’on dessinera un ovale. On part du même code source que précédemment en rajoutant une classe Rlabel.
require 'java'
include_class 'javax.swing.JFrame'
include_class 'javax.swing.JLabel'
include_class 'java.lang.Runnable'
include_class 'java.awt.EventQueue'
class RLabel < JLabel
def paint(g)
g.fillOval(10, 10, 20, 20)
end
end
class App < Runnable
def run
frame = JFrame.new('JRuby & Swing');
frame.setSize(320, 200)
frame.getContentPane.add(RLabel.new('A Ruby label in Swing !'))
frame.setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
frame.setVisible(true)
end
end
EventQueue.invokeLater(App.new)
Puis on exécute le script avec la commande suivante.
java -jar jruby.jar swing2.rb
Malheureusement le résultat est le même que précédemment. En effet notre redéfinition de paint n’a pas été appelée. Dans ce cas on va essayer de créer un RComponent qui héritera directement de JComponent. Voici le contenu de swing3.rb.
require 'java'
include_class 'javax.swing.JFrame'
include_class 'javax.swing.JLabel'
include_class 'javax.swing.JComponent'
include_class 'java.lang.Runnable'
include_class 'java.awt.EventQueue'
class RComponent < JComponent
def paintComponent(g)
g.setColor(Color::GREEN);
g.FillOval(50, 50, 100, 100)
end
end
class App < Runnable
def run
frame = JFrame.new('JRuby & Swing');
frame.setSize(320, 200)
frame.getContentPane.add(RComponent.new)
frame.setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
frame.setVisible(true)
end
end
EventQueue.invokeLater(App.new)
Hélas lors de l’exécution voici ce que l’on obtient.
java -jar jruby.jar swing3.rb
Exception in thread "AWT-EventQueue-0" org.jruby.exceptions.RaiseException: can't make instance of javax.swing.JComponent
En visitant la page limitations de JRuby on comprend pourquoi nous y sommes pas arrivé. En effet il n’est pas possible de dériver une classe abstraite (bien que l’on peut implémenter des interfaces). Par contre on peut dériver des classes Java mais ce ne sera pas visible côté Java.
En conclusion on peut déjà jouer avec Jruby mais certaines limitations sont trop contraignantes pour construire une application entièrement sur Jruby afin de méler Ruby et Java. Cependant il n’est pas bête de construire un système de plugins avec JRuby.
Dans cette même page il est mentionné que ces contraintes seront résolues lorsqu’ils auront un compilateur. Oui mais de quel genre? YARV? Ruby2Java?


