Présentation de Ruby…

Ruby est un langage interprété, orienté objet et dynamique créé par un Japonais, Yukihiro "Matz" Matsumoto, en 1995. Le langage est resté discret pendant des années car la plupart des ressources que l'on pouvait trouver étaient en japonais. Mais l'apparition du framework web Ruby On Rails en 2004 a permis un gain de popularité extrêmement rapide. Ruby s'inspire principalement de 3 langages : SmallTalk, Python et Perl pour allier le modèle objet de Smalltalk, la simplicité de Python et la flexibilité de Perl. La version actuelle de Ruby est la 1.8.6 et l’on peut la télécharger à l'adresse suivante : http://www.ruby-lang.org. La version 1.9 est actuellement en développement et devrait être disponible au alentours de Noël.

Ruby est intégré à Mac OS X et des paquets sont disponibles pour toutes les distributions Linux. Pour Windows, il suffit d'aller sur le site de Ruby et de télécharger l'installeur. A noter que Ruby devrait être intégré à Windows Vista dans quelques temps via le framework .NET. Il n'y a donc pas de raison de ne pas s'en servir.

Syntaxe de base

La syntaxe est d'une très grande simplicité. Les points-virgules à la fin des lignes et les parenthèses sont optionnelles. Les blocs ne sont plus délimités par des accolades, mais finissent par le mot-clé end. Voici un exemple de syntaxe :

if i == 0
    puts "i vaut 0"
end

Mais on pourrait très bien écrire notre code avec des parenthèses et des points-virgules :

if (i == 0)
    puts("i vaut 0);
end

La flexibilité de la syntaxe permet aux développeurs d'avoir ses préférences. Cependant, pour le travail en équipe, une plus grande rigueur devra être mis en place.

Les variables en Ruby sont fortement typées, mais le typage se fait dynamiquement, il ne faut donc pas indiquer le type pour une variable.

Enfin, un autre point très intéressant dans Ruby est le modèle objet. La règle dans le langage est "tout est objet". En Ruby, tout est donc objet mis à part les structures de contrôle. La création d'une fonction crée en fait une méthode de la classe Object, racine des classes de Ruby.

Blocs et itérateurs

Dans les autres langages de programmation, les blocs sont souvent entre accolades. En Ruby, cette syntaxe existe, mais on peut aussi utiliser do ... end qui est une façon plus littéraire de délimiter un bloc. On pourra aussi passer des arguments au bloc via le sous-bloc. Pour créer un bloc, nous allons utiliser le mot clé yield. Créons pour cela une méthode :

def compteur
    yield
end

En appelant cette fonction, il faudra faire un bloc qui remplacera yield :

compteur do
    puts "1, 2, 3, 4, 5"
end

Affichera :

1, 2, 3, 4, 5

Il est nécessaire de comprendre ce concept pour assimiler ensuite les itérateurs. Pour passer des arguments, il suffit d'indiquer les arguments au yield et à l'appel du bloc :

class Integer
    def plus5
        nb = self + 5
        yield nb
    end
end

3.plus5 do |i|
    puts i
end

Ici, nous étendons la classe Integer (un entier est une instance de la classe Integer) en ajoutant une méthode plus5. Cette méthode va ajouter 5 à l'entier et il va être passé en argument au bloc pour ensuite avoir la possibilité de traiter le résultat. L'exemple ci-dessus affichera :

8

On retrouve quelques nouveautés au niveau des structures de contrôle. En plus des if, while, case (équivalent du switch) et for, il y a unless (sauf si), until (jusqu'à). Il y a aussi un certain nombre d'itérateurs. Les 2 plus courants sont times et each. Pour répéter une instruction n fois, nous utilisons généralement la boucle for. Ici il faudra utiliser times :

3.times do
    puts "Bonjour"
end

La lecture est tout de même plus aisée que la boucle for. Ce code affichera 3 fois Bonjour :

Bonjour
Bonjour
Bonjour

Si au lieu d'afficher Bonjour, on veut afficher le nombre de l'itération courante, il suffira de rajouter l'argument permettant sa gestion à notre itérateur :

3.times do |i|
    puts i
end

Il en résultera l'affichage suivant :

0
1
2

On voit donc bien ici qu'un itérateur n'est en fait qu'une simple méthode à l'intérieur de laquelle se trouve un yield. Essayons maintenant l'itérateur each. Il permet de parcourir une collection :

[1, 2, 3, 4, 5].each do |item|
    puts item
end

Nous créons ici un tableau. Vu qu'en Ruby tout est objet, il n'y a aucunement besoin d'assigner le tableau à une variable avant de pouvoir l'utiliser. C'est très utile si nous ne l'utilisons qu'une seule fois. Nous pouvons donc directement appeler notre itérateur. Ici le paramètre sert à récupérer l'élément courant du tableau. Ce code affichera :

0
1
2
3
4
5

for ne peut pas être utilisé pour remplacer times mais each oui :

for item in [1, 2, 3, 4, 5]
    puts item
end

Modèle objet

Comme je l'ai dit tout à l'heure, Ruby est un langage tout objet. Un entier est une instance de la classe Integer, une chaîne de caractère est une instance de la classe String... Comment utiliser tout ça ? Tout d'abord, les classes déjà définies comportent un certain nombre de méthodes. Utilisons la méthode length de la classe String :

"Bonjour".length

Cette méthode va nous retourner un entier correspondant au nombre de caractères de la chaîne. Si l'on veut incrémenter la valeur, on utilise la méthode next de la classe Integer :

"Bonjour".length.next

Ruby nous permet d'étendre une classe très facilement. On peut donc ajouter une méthode à la classe Integer en quelques lignes :

class Integer
    def plus5
       self + 5
    end
end

Ici, nous ajoutons une méthode nommée plus5 qui retournera l'addition du nombre actuel avec 5. On peut accéder à la valeur à l'intérieur de la classe avec le mot-clé self (c'est l'équivalent du mot-clé this que l'on retrouve dans les langages dérivants du C). Une autre particularité de Ruby est le caractère optionnel du mot-clé return. Si ce dernier n'est pas indiqué, c'est la dernière expression évaluée qui est retournée. Maintenant, on veut créer une classe Personne :

class Personne
    attr_accessor :prenom, :nom

    def initialize prenom, nom, age
       @prenom = prenom
       @nom = nom
       @age = age
    end

    def majeur?
       true if @age > 18
    end
end

La méthode initialize est notre constructeur et l’on va insérer nos valeurs aux variables de classe prenom, nom et age (le arobase préfixant les noms des variables signifie que ce sont des variables d'e classe). Il y a aussi une méthode pour savoir si la personne est majeure ou pas. En Ruby, si une méthode retourne un booléen, elle se finit par un point d'interrogation, mais ce n'est pas obligatoire. Nos variables de classe ne sont utilisables qu'à l'intérieur de la classe. Si nous voulons les utiliser où l'on veut, il va falloir faire des accesseurs. Pour cela nul besoin de créer des méthodes à la main comme c'est le cas en Java. Il suffit d'utiliser la syntaxe suivante :

attr_accessor :prenom, :nom

De ce fait, nos variables de classe prenom et nom seront accessibles en lecture et en écriture depuis n'importe où. Avec attr_reader, l'accès ne se fera qu'en lecture (get) et avec attr_writer qu'en écriture (set). Testons maintenant notre classe :

personne1 = Personne.new "John", "Smith", 47
puts "Bonjour #{personne1.prenom} #{personne1.nom}" if personne1.majeur?

L'instanciation de la classe se fait par le mot-clé new. Ensuite nous pouvons utiliser les variables et les méthodes définies. Encore une petite particularité de Ruby, au lieu de concaténer nos variables avec la chaîne de caractère avec + (ce qui fonctionne), nous utilisons la syntaxe #{...} qui permet d'insérer du code Ruby à l'intérieur d'une chaîne de caractère. Cet exemple affichera :

Bonjour John Smith

Si nous voulons une classe qui va être un peu plus spécialisée, par exemple Homme, il sera mieux de dériver la classe de Personne que de tout refaire :

class Homme < Personne
    def initialize prenom, nom, age
       super prenom, nom, age
       @sexe = "h"
    end
end

La méthode super permet d'appeler le constructeur de la classe mère. Pour le reste, c'est assez classique. Finissons le modèle objet par une autre particularité du Ruby : les mixins. Contraction de Mixed in, cela signifie que l'on va pouvoir mixer du code à l'intérieur de notre classe pour qu'il devienne une partie de notre classe. Pour cela, on va utiliser des modules. Ces derniers sont similaires aux classes à l'exception qu'ils ne peuvent être instanciés. On peut comparer un module à un espace de noms dans certaines utilisations. Nous voulons séparer le code traitant de l'âge légal de la classe. Pour cela, tout ce qui concerne l'âge légal va être mis dans un module ayant pour nom AgeLegal :

module AgeLegal
    def majeur?
        true if @age > 18
    end
end

Une fois le module inclu, le code se comporte comme s'il avait été écrit dans la classe directement.

class Personne
    include AgeLegal

    attr_accessor :prenom, :nom

    def initialize prenom, nom, age
       @prenom = prenom
       @nom = nom
       @age = age
    end
end

Grâce aux mixins, Ruby garde les avantages de l'héritage simple tout en ayant les avantages de l'héritage multiple.

Que penser de Ruby ?

Ruby est un langage qui peut dérouter un nombre important de personnes car la syntaxe et les concepts sont différents de la philosophie des principaux langages dérivant presque tous du C. Mais si on passe cette barrière, on découvre vite un langage adapté à la pensée du développeur qui arrive à allier la simplicité et l'ingéniosité.

Ruby On Rails

Ruby On Rails, que l'on peut aussi appelé RoR ou juste Rails, est un framework web créé par David Heinemeier Hansson et qui a commencé à faire parler de lui en Juillet 2004. La popularité de ce framework a vite explosé et d'autres frameworks, notamment en PHP, sont apparus rapidement. Rails est aujourd'hui une solution de plus en plus adoptée dans le développement web et vient faire de l'ombre à ASP.NET, J2EE et PHP. Près d'un tiers des nouvelles embauches dans le développement web aux Etats Unis se font pour du Ruby On Rails, des sites très importants comme Twitter sont fait avec Ruby On Rails, signe que le framework est fiable. La version 1.0 est sortie en Décembre 2005 et la dernière version en date, 2.0, qui devrait sortir dans les prochaines semaines. Cet article va d'ailleurs utiliser des nouveautés de Rails 2.0.

Si ce framework est utilisé, ce n'est pas en raison d'un mouvement de mode, mais c'est qu'il comporte de nombreux avantages pour un développement simple, agile et robuste. Rails est un framework MVC (Modèle Vue Contrôleur) permettant ainsi de bien séparer l'accès aux données, de l'affichage et des actions. La plupart des frameworks web actuels utilisent cette même architecture. Il y a 2 autres idées que le framework reprend, DRY (Don't Repeat Yourself) qui est un principe selon lequel aucune définition ne peut être présente plusieurs fois et "convention over configuration" qui a pour but de générer automatiquement un grand nombre de choses à l'aide de conventions et de ne seulement configurer que les cas particuliers.

Cela fait 2 ans que je développe avec Ruby On Rails (un peu avant la sortie de la version 1.0) et j'ai bien plus de plaisir à développer maintenant qu'avant avec PHP. J'ai pris part à la communauté et en parle régulièrement sur mon blog, Boldr. Je développe tous les jours avec Ruby On Rails grâce à la société que j'ai créé, Yeasty Mobs (qui ne se serait pas faite si je n'étais pas passé à Ruby On Rails). Sans ce framework, je n'aurais surement pas autant de plaisir à faire toutes ces activités et je vais donc vous montrer pourquoi j'aime autant RoR au travers d'un tutoriel montrant toutes les bases, en sachant que ce n'est que la partie visible de l'iceberg.

Rendez-vous ici-même dans quelques jours pour un tutoriel très complet pour bien démarrer avec Ruby on Rails