Extraction du Ruby
Vous voulez apprendre la
programmation ? Ou tout simplement un nouveau
langage ?
Vous avez entendu parler de
Ruby on Rails sans
savoir ce que c'est ?
L'anglais et le japonais vous donnent des nausées ?
Quand même envie de vous lancer ?
Ce tutoriel est fait pour vous, il vous apprendra à programmer en
Ruby et à utiliser
Ruby on Rails,
même si vous êtes de vrais débutants,
et tout ça en français, oui messieurs-dames.
Ruby est un langage de script interprété et orienté objet proche du
Python, du Perl et du Smalltalk. Pour convaincre les plus réticents
d'entre vous, précisons que Ruby est un langage gratuit, simple,
libre, portable, complet, multithread, etc.
Ce cours est composé des parties
suivantes :
-
Partie 1 : Se familiariser avec Ruby
Avant de commencer, voici de quoi en savoir un peu plus sur ce
langage. Développé par
Yukihiro Matsumoto (un
développeur japonais) depuis 1993, il séduit de plus en plus de
programmeurs par sa simplicité (syntaxe limpide), sa puissance et
sa productivité. Il est gratuit, entièrement libre (sous licences
GPL et Ruby), portable, multithread, mais également très
complet ; on peut tout faire en Ruby : manipulation de fichiers,
méta-programmation, gestion de XML, PDF, HTML, ZIP, etc., bases de
données, requêtes HTTP, HTTPS, FTP, DNS, POP3, programmation web,
réseau, graphique, et j'en passe... Il n'est pas dit que tout sera
abordé dans ce tutoriel.
Ruby possède une syntaxe et une approche assez
semblables à celles d'autres langages comme le Python, le Perl ou
le PHP. Si vous maîtrisez déjà quelques uns de ces langages,
l'apprentissage de Ruby ne vous sera que plus simple. Attention
néanmoins, cela n'empêche pas Ruby d'avoir ses propres
particularités (et ses propres pièges) : il est plus sage de lire
attentivement tous les chapitres (en entier et en suivant l'ordre
donné) de cette première partie.
Si vous êtes un zéro pur boeuf et ne connaissez aucun autre
langage, pas de panique, vous arriverez quand même à apprendre le
Ruby sans problème.
Cette première partie vous enseignera les bases du langage (elles
sont indispensables), ainsi que quelques généralités qu'il est
toujours bon de savoir.
J'espère que cette première partie vous a donné envie d'aller plus
loin dans votre apprentissage du Ruby. La suite du tutoriel vous
fera découvrir des aspects plus poussés du langage, ainsi que le
jeune mais néanmoins prometteur Ruby on Rails.
-
Partie 2 : Pratiques avancées
Pourquoi se limiter aux bases d'un
langage qui brille par sa simplicité ?
...
Ne cherchez pas, il n'y a pas de réponse.
Je vous propose donc de passer à la vitesse supérieure et d'aborder
des aspects plus poussés du langage, avec (entre autres) les bases
de données, les expressions régulières, les threads, etc. Que de
réjouissances en perspective.
Comme promis, la prochaine partie du tutoriel sera consacrée à Ruby
on Rails, je vous y attends.
Cette partie n'est pas terminée.
-
Partie 3 : Ruby sur le Net : Ruby on Rails
Mais Ruby c'est aussi
Ruby on Rails : un
framework, c'est à dire un ensemble
de bibliothèques et de conventions permettant le développement
rapide d'applications. C'est un outil de développement très
productif qui s'appuie sur le langage Ruby (j'espère que vous vous
êtes intéressés à la première partie
).
Il permet de développer des
applications web
riches (et donc des pages dynamiques) en Ruby et peut être
associé aux technologies AJAX (JavaScript + XML) et même PHP. Vous
apprendrez à tirer profit de ces possibilités dans cette troisième
partie.
Histoire de vous faire saliver, voici un annuaire recensant des
applications web créées avec Rails :
BusinessOnRails.com
Cette partie n'est pas terminée.
-
Partie 4 : Annexes
Dans les Annexes vous trouverez des chapitres additionnels,
liés à certains aspects du cours, dont la lecture n'est pas
obligatoire ; à lire quand vous voulez et pas nécessairement à la
fin.
Partie 1 : Se familiariser avec Ruby
Avant de commencer, voici de quoi en savoir un peu plus sur ce
langage. Développé par Yukihiro Matsumoto (un
développeur japonais) depuis 1993, il séduit de plus en plus de
programmeurs par sa simplicité (syntaxe limpide), sa puissance et
sa productivité. Il est gratuit, entièrement libre (sous licences
GPL et Ruby), portable, multithread, mais également très
complet ; on peut tout faire en Ruby : manipulation de fichiers,
méta-programmation, gestion de XML, PDF, HTML, ZIP, etc., bases de
données, requêtes HTTP, HTTPS, FTP, DNS, POP3, programmation web,
réseau, graphique, et j'en passe... Il n'est pas dit que tout sera
abordé dans ce tutoriel.
Ruby possède une syntaxe et une approche assez
semblables à celles d'autres langages comme le Python, le Perl ou
le PHP. Si vous maîtrisez déjà quelques uns de ces langages,
l'apprentissage de Ruby ne vous sera que plus simple. Attention
néanmoins, cela n'empêche pas Ruby d'avoir ses propres
particularités (et ses propres pièges) : il est plus sage de lire
attentivement tous les chapitres (en entier et en suivant l'ordre
donné) de cette première partie.
Si vous êtes un zéro pur boeuf et ne connaissez aucun autre
langage, pas de panique, vous arriverez quand même à apprendre le
Ruby sans problème.
Cette première partie vous enseignera les bases du langage (elles
sont indispensables), ainsi que quelques généralités qu'il est
toujours bon de savoir.
Pour commencer
Ruby est un langage interprété, c'est-à-dire que vous devez
posséder un interpréteur sur votre ordinateur pour exécuter vos
programmes.
Ces fichiers possèdent l'extension
.rb.
Certains systèmes d'exploitation sont initialement pourvus de cet
interpréteur, pour d'autres il faudra le télécharger. Ne prenez en
compte que la partie concernant votre propre système
d'exploitation.
Installer Ruby
GNU / Linux
Ruby est préinstallé sur de nombreuses distributions de Linux
(Fedora Core par exemple), mais ceci n'étant qu'une généralisation,
tout dépend de la distribution que vous possédez. Je ne saurais
vous dire mieux que de vous référer à la partie concernant GNU /
Linux sur cette
page.
Microsoft Windows
La solution la plus simple pour les utilisateurs de Windows
consiste à télécharger un installeur qui fera tout le travail à
votre place. La dernière version stable à l'heure où j'écris ces
lignes est la 1.8.5, rendez-vous sur cette page pour la
télécharger. Si vous suivez les instructions données par
l'installateur, tout se passera sans encombre.
Pour lancer la console allez dans
Démarrer > Tous les programmes >
Accessoires > Invite de commande.
Pour que ce soit plus pratique à l'avenir : clic droit > envoyer sur le bureau (en tant
que raccourci).
Puis clic droit > Propriétés >
Raccourci > Démarrer dans > C:\Prog (le dossier où
vous comptez mettre vos programmes).
FreeBSD
Ruby fait partie de la collection des ports de FreeBSD. Vous pouvez
donc l'installer en entrant les instructions suivantes dans un
terminal :
Code : Console - Afficher / masquer les numéros de
ligne
# cd /usr/ports/lang/ruby
# make
# make install
# make clean
MAC OS X
Ruby est distribué par défaut avec Mac OS X, donc normalement tout
va bien, ça fait quoi de se sentir privilégié ?
Vérification de routine
Afin de vérifier que vous disposez dès lors bien de Ruby sur votre
ordinateur, lancez la console (ou terminal) et entrez-y
l'instruction :
Code : Console - Afficher / masquer les numéros de
ligne
Vous devriez obtenir un message semblable à celui-ci :
Code : Console - Afficher / masquer les numéros de
ligne
ruby 1.8.5 (2006-08-25) [i386-mswin32]
Si tel est le cas, félicitations, vous allez pouvoir passer à
l'étape suivante, sinon relisez la section correspondant votre
système d'exploitation, vous avez dû oublier quelque chose.
Ecrire du code Ruby
Seul l'interpréteur étant requis, vous n'aurez besoin d'aucun autre
programme spécifique pour écrire ou lire du code Ruby.
Un éditeur de texte quelconque (comme le Bloc-notes) suffit, mais
il en existe aussi proposant une coloration syntaxique du code
:
Sachez également que Ruby possède aussi son propre IDE : FreeRide
(The Free Ruby IDE) fourni avec
l'interpréteur. Bref, ce n'est pas le choix qui manque ; pour ma
part, j'utilise SciTE pour tous les langages interprétés, votre
choix n'aura aucune incidence sur la suite de votre parcours.
Interpréter un programme Ruby
Pour lancer un programme Ruby, démarrez la console et entrez-y
l'instruction suivante :
Code : Console - Afficher / masquer les numéros de
ligne
où votreProg est le nom de votre
programme et .rb l'extension naturelle des fichiers écrits
en Ruby.
Votre programme doit se trouver dans le
même répertoire que le répertoire-cible de la console.
Par exemple, si vous avez quelque chose du genre :
Code : Console - Afficher / masquer les numéros de
ligne
C:\repertoirePerso\mesFichiers\
vous devez veiller à ce que vos programmes Ruby s'y trouvent, ou
bien modifiez ce chemin par vous-mêmes ; pour ce faire :
Code : Console - Afficher / masquer les numéros de
ligne
cd votreRepertoire
cd D:\
cd ruby/Test
cd est l'abréviation de change directory (changement de répertoire), et
vous permet de vous déplacer dans l'arborescence de votre
disque.
Pour Windows, j'ai indiqué une astuce
plus haut : vous pouvez créer des raccourcis de la console et les
faire pointer directement vers le répertoire voulu : ainsi, plus
besoin d'utiliser cd.
Vous êtes maintenant capables d'écrire et d'exécuter des programmes
Ruby, nous allons maintenant apprendre à tirer parti de ce langage.
Structure d'un programme
Ceci est une brève parenthèse avant de commencer, on en aura besoin
de toutes façons donc autant s'en occuper de suite.
Les commentaires
Les commentaires sont tout simplement du texte dont le but est
d'apporter un complément
d'information concernant un élément obscur du code, afin
d'en faciliter la relecture a
posteriori et la maintenance. L'information présentée doit
alors être concise et précise, elle tient généralement en une seule
ligne, on utilise alors le symbole #
(dièse ou sharp).
Tout texte situé à droite de ce
symbole sera ignoré par l'interpréteur, jusqu'à un retour à la
ligne.
Code : Ruby
# ceci est un
commentaire
Il peut arriver d'avoir besoin d'étendre des commentaires sur
plusieurs lignes, dans ce cas, au lieu de faire débuter chaque
nouvelle ligne par un #, vous pouvez
encadrer votre paragraphe par =begin
et =end. Tout ce qui se trouvera
alors entre ces deux mots sera tout bonnement ignoré. Voici un
exemple :
Code : Ruby
=begin
ceci
ceci, et ceci également
=end
Les délimiteurs d'instruction
Les instructions du programme sont usuellement séparées par un
point-virgule (situé en fin de ligne).
Ruby (contrairement à certains autres langages) vous permet
d'omettre ce point-virgule si vous vous limitez à une seule
instruction par ligne. Nous utiliserons cette particularité tout le
long du tutoriel.
On va pouvoir se lancer maintenant.
Un langage Orienté Objet
Ruby est un langage de programmation orienté
objet, ça vous le savez déjà. La programmation orientée
objet (abrégée POO) est simplement une
technique de programmation, tout
comme la programmation dite impérative qui caractérise le C ou le PHP et qui
n'est qu'une succession d'étapes (conditions, boucles, etc.). Il
existe d'autres types de programmation, mais leur étude n'est pas
le but de ce tutoriel.
La POO s'organise autour de Classes et, comme son
nom le suggère, d'Objets. C'est donc une nouvelle
manière d'organiser sa pensée (un paradigme pour les puristes), et par la même
occasion son programme. Voyons les avantages qu'elle représente aux yeux des
programmeurs.
Les principes de la POO sont assez
difficiles à comprendre la première fois (quel que soit le
langage). Aussi, n'hésitez pas à relire ce chapitre une deuxième
fois, ça passera mieux.
Quel intérêt ?
Réutilisation du code
Imaginons que vous vouliez créer un programme affichant une fenêtre
contenant une image. Vous codez le tout sans problème : le nom de
la fenêtre, ses dimensions, sa disposition et son contenu. Puis vos
compétences en programmation augmentent et vous vous sentez aptes à
créer un jeu de morpion en fenêtre. Seulement voilà : créer une
fenêtre, vous savez le faire, vous l'avez d'ailleurs déjà fait un
peu plus tôt (votre programme basique affichant une image dans une
fenêtre).
Les programmeurs et leur légendaire fainéantise ont pensé à une
manière de réutiliser un code déjà
existant. C'est là qu'intervient la POO : en tirant partie
de ce concept fournissant Objets et Classes, voyons ce que nous
pouvons faire pour notre exemple : nous allons définir une classe
Fenetre et nous servir d'elle à
chaque fois que nous voulons créer une nouvelle fenêtre : de cette
manière, on évite le code inutile.
Un autre avantage découle de celui-ci, il s'agit de l'encapsulation.
L'encapsulation
Un autre concept obscur, me direz-vous !
C'est en fait un mot compliqué pour pas grand-chose : en effet,
elle désigne le fait de masquer les informations contenues dans un
Objet, et de les rendre accessibles par des méthodes (voir chapitre suivant). Ces informations sont
encapsulées dans l'objet. Ainsi,
toute la partie technique du code est contournée.
Dans notre exemple : pour modifier la couleur de fond de notre
fenêtre, il nous suffit de créer une méthode changerCouleurFond contenant les instructions
techniques permettant d'accéder à la couleur de fond de la fenêtre,
puis de la modifier. Ensuite, nous l'utiliserons chaque fois que le
besoin se fera sentir. De plus, l'information de la couleur de fond
de la fenêtre ne sera pas accessible et ne pourra donc pas être
modifiée en dehors de cette méthode. N'est-ce pas plus pratique ?
Les Classes
Une classe est une catégorie d'objets : elle déclare des propriétés
et des méthodes communes aux objets qu'elle définit (on dit
qu'une classe instancie des objets ou
qu'elle crée des instances de ces différents objets). On pourrait
comparer une classe à un moule, les objets qu'elle définit étant
basés sur le modèle de cette classe.
Ainsi, notre classe Fenetre regroupe
toutes les informations et toutes les méthodes communes aux
fenêtres, elle nous servira de modèle chaque fois que nous voudrons
en créer une.
Voici par exemple trois classes existantes :
- les entiers sont des objets de la classe Integer
- les flottants (les nombres à virgule) sont des objets de la
classe Float
- les chaînes de caractères (caractères alphanumériques délimités
par des guillemets ou des apostrophes) sont des objets de la classe
String.
Pour déclarer une classe quelconque, il faut procéder ainsi :
Code : Ruby - Afficher / masquer les numéros de
ligne
Le mot-clé class débute la
déclaration d'une classe et le mot-clé end se charge de la terminer. Les noms de classes
(ici Fenetre) débutent toujours par une lettre majuscule.
L'héritage
L'orientation objet de Ruby permet de faire hériter certaines
classes d'autres classes. C'est là qu'intervient la notion de
sous-classe. Par défaut, les
sous-classes héritent des méthodes de leur super-classe : elles ont le même comportement.
Mais l'intérêt est que vous pouvez vous servir des sous-classes
pour modifier des méthodes (voir chapitre
suivant) ou en ajouter de nouvelles . Cet exemple simple montre comment
définir une classe héritant d'une super-classe :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Machine
-
#
-
end
-
-
class Ordinateur <
Machine
-
#
-
end
Dans la définition de la classe Ordinateur, <
Machine indique que cette classe est une sous-classe de la
classe Machine.
Vous pouvez modifier une classe (pour
y ajouter des méthodes, par exemple) sans disposer de son code
d'origine.
Les Objets
Un objet est un ensemble de données (d'informations le concernant)
et de méthodes, défini par sa classe. Il est du type de sa classe,
par exemple 14 est un objet de la classe Integer, il dispose des méthodes définies par
cette classe.
Si nous voulons créer un objet de type Fenetre (une instance de la classe Fenetre), celui-ci disposera des méthodes de
cette classe.
Création d'objets
Les objets de type standard comme les nombres (entiers ou
flottants), les chaînes de caractères, les symboles, les tableaux,
etc. sont créés par simple déclaration.
Code : Ruby
a = 5 # nouvel objet de type Integer
b = 5.7
# nouvel objet de type Float
c = "coucou" # nouvel
objet de type String
Pour tous les autres (ceux que vous avez vous mêmes créés), on
utilise la méthode new (vous
commencez à saisir ce qu'est une méthode ? non ? de toutes façons
elles seront bientôt expliquées ). Par exemple pour créer un objet de la classe
Ordinateur, voici ce qu'il faut faire
:
Code : Ruby
class
Ordinateur
#
end
laptop = Ordinateur.new # laptop est une nouvelle instance de la classe
Ordinateur
Pour terminer notre tour d'horizon de la POO, il vous reste les
méthodes : le chapitre suivant y est consacré.
Les méthodes (1/2)
Ce chapitre est la suite directe du précédent, vous verrez enfin ce
que sont les méthodes.
Définition
Une méthode est un ensemble d'instructions réalisant une certaine
tâche (par exemple : faire une addition, créer une fenêtre, etc.).
Elle est liée à un objet : si nous ajoutons une méthode
fermerFenetre dans notre classe
Fenetre, cette méthode est liée aux
objets de type Fenetre.
Les méthodes sont définies par le mot-clé def et leur déclaration se clôt par un
end.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
def compter # définition de la méthode compter
-
#
-
end
Vous pouvez passer des arguments à vos méthodes, ce sont des
paramètres qui peuvent influencer sur le résultat de l'exécution de
la méthode en question. Ils sont indiqués entre parenthèses (elles
sont optionnelles), et sont séparés par des virgules :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
def compter(arg1, arg2)
-
#
-
end
Ces paramètres peuvent bien évidemment être récupérés, nous verrons
comment stocker des données dans le chapitre suivant.
Les méthodes sont couramment déclarées
à l'intérieur des classes, mais vous pouvez également les déclarer
en dehors. Comme en Ruby tout est objet, elle seront de toutes
façons reliées à la super-classe Object.
Nous avons vu comment instancier un nouvel objet ; voyons comment
utiliser une de ses méthodes :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Ordinateur
-
def run
-
puts "hello world
!"
-
end
-
end
-
-
monOrdi = Ordinateur.new
-
monOrdi.run # appel de la méthode run
Nous appelons ici la méthode run de
notre objet monOrdi de type
Ordinateur. L'appel est semblable à
celui de la méthode new.
La méthode initialize
Lors de l'instanciation d'un nouvel objet (appel de new), l'interpréteur vérifie si une méthode
initialize est associée à cet objet,
si c'est le cas il l'exécute :
Code : Ruby
class
Ordinateur
def
initialize
puts "nouvel ordinateur
!"
self.run
end
def run
puts "hello world
!"
end
end
monOrdi = Ordinateur.new
On obtient :
Code : Console
nouvel ordinateur !
hello world !
La méthode initialize est appelée dès
l'instanciation, elle appelle ensuite la méthode run. Le mot-clé self fait référence à l'objet qui appelle la
méthode, ici monOrdi ; donc
self.run équivaut à écrire
monOrdi.run à l'extérieur de la
classe :
Code : Ruby
monOrdi = Ordinateur.new
monOrdi.run
self est implicite donc vous pouvez
simplement écrire :
Code : Ruby
def initialize
puts
"nouvel ordinateur !"
run # appel de la
méthode run
end
Si la méthode initialize n'a pas été
trouvée dans la définition de la classe, l'interpréteur en cherche
une dans les super-classes de la classe en question, par exemple
:
Code : Ruby
class
GrandParent
def
initialize
puts "visite
:o)"
end
end
class Parent < GrandParent;
end
class Enfant < Parent; end
me = Enfant.new
On obtient :
Code : Console
visite &#58;&#111;)
Oui je m'amuse bien, je vous remercie. Ici, la classe Enfant, ne dispose pas d'initialize, on inspecte sa super-classe
Parent ; elle n'en possède pas non
plus, on va regarder du côté de sa super-classe GrandParent ; on appelle la méthode initialize de la classe GrandParent.
Redéfinition de méthodes
On peut redéfinir une méthode pour en modifier le comportement,
pour cela, faites comme si vous écriviez cette méthode pour la
première fois. Si elle est inclue dans une classe, redéfinissez-la
également :
Code : Ruby
class
Ordinateur
def run
puts "Hello
?"
end
end
monOrdi = Ordinateur.new
monOrdi.run # méthode
originelle
####
class Ordinateur # on
redéfinit la classe
def run
# on redéfinit la méthode
puts "Hello world
!"
end
end
monOrdi.run # méthode
redéfinie
On obtient :
Code : Console
Hello ?
Hello world !
La méthode initialize peut également
être redéfinie.
La redéfinition peut aussi servir à différencier la méthode d'une
sous-classe héritée de la méthode de sa super-classe comme nous
l'avons vu avec la notion d'héritage. Un exemple :
Code : Ruby
class Machine
def run
puts "je suis une
machine"
end
end
class Ordinateur < Machine
def run
puts "je suis un
ordinateur donc une machine" # on
redéfinit la méthode run héritée de Machine
end
end
objet1 = Machine.new
objet1.run # méthode
originelle
objet2 = Ordinateur.new
objet2.run # méthode
redéfinie
On obtient donc :
Code : Console
je suis une machine
je suis un ordinateur donc une machine
Méthodes privées et protégées
Tout d'abord, vous devez savoir que par défaut, les méthodes sont
dites publiques, c'est à dire
qu'elles sont accessibles à l'intérieur comme à l'extérieur de la
classe, de même que par les sous-classes de la classe en question.
Elles sont donc utilisables partout.
En plaçant le mot-clé public au sein
de la classe, toutes les méthodes déclarées après seront publiques.
Ce mot est optionnel et toutes les méthodes déclarées au début de
la classe seront publiques jusqu'à ce qu'on place un autre mot-clé
pour changer l'accès
:
Code : Ruby
class Machine
def initialize
# méthode publique par défaut
run
end
public #
optionnel
def run
puts "je suis une
machine"
end
end
Nous voyons ici que run est
accessible depuis l'extérieur de la classe :
Code : Ruby
monOrdi = Machine.new
monOrdi.run
Pour éviter cela, nous pouvons réglementer l'accès à certaines
méthodes en les rendant privées ou
protégées, voyons de quoi il
retourne.
Les méthodes privées
Le mot-clé à placer pour déclarer des méthodes privées est
private :
Code : Ruby
class Machine
def run
print "machine"
end
private
def
run_private
print "
privee"
end
end
Toutes les méthodes déclarées après le mot-clé private sont privées, jusqu'à (éventuellement) un
autre changement d'accès.
Les méthodes privées ne sont accessibles
qu'à l'intérieur de la classe elle-même et de ses sous-classes, pas
à l'extérieur !
Ainsi, en considérant la classe définie plus haut :
Code : Ruby
monOrdi = Machine.new
monOrdi.run #
correct
monOrdi.run_private #
erreur
En appelant la méthode privée run_private depuis l'extérieur de la classe on
obtient bien entendu une erreur, en revanche, cette méthode peut
être appelée depuis la méthode run
(qui est publique) par exemple en la redéfinissant de cette manière
:
Code : Ruby
def run
print
"machine"
run_private
end
Et monOrdi.run est tout à fait
correct.
Les méthodes protégées
Le fonctionnement des méthodes protégées est (quasi) le même que
celui des méthodes privées ; le mot-clé changeant l'accès de ces
méthodes est protected :
Code : Ruby
class Machine
def run
print "machine"
run_protect
end
protected
def
run_protect
print "
protegee"
end
end
Les méthodes protégées sont accessibles depuis la classe et ses
sous-classes, mais pas depuis l'extérieur. Ainsi, l'appel de
run_protect depuis l'extérieur de la
classe provoque une erreur, mais l'appel à run (elle-même appelant run_protect) est correct.
Alors me direz-vous, pourquoi distinguer
ces deux types de méthodes ?
Avez-vous essayé d'appeler des méthodes privées d'un autre objet de
type Machine ? Eh bien, on ne peut
pas ! Considérons cette classe :
Code : Ruby
class Machine
def
run(autre);
print "je suis une
machine"; autre.run_private;
end
private
def
run_private; print "
privee"; end
protected
def
run_protect; print "
protegee"; end
end
Créons deux objets de type Machine et
appelons la méthode run de l'un d'eux
en passant l'autre en paramètre. La méthode run appelera la méthode run_private de l'objet passé en paramètre et ça
plantera :
Code : Ruby
monOrdi = Machine.new
tonOrdi = Machine.new
monOrdi.run(tonOrdi)
Essayons maintenant d'appeler la méthode protégée à la place de la
méthode privée, pour cela redéfinissons la méthode run :
Code : Ruby
def
run(autre);
print "je suis une
machine"; autre.run_protect;
end
La méthode run a ici appelé la
méthode run_protect (protégée) de
l'objet tonOrdi, sans erreur. C'est
une des principales différences entre les méthodes privées et
protégées.
Autres précisions
Si vous voulez que des méthodes déclarées après d'autres méthodes
privées ou protégées soient publiques, vous devez (re)placer le
mot-clé public avant leur déclaration
:
Code : Ruby
class Machine
def
initialize; run; end
private
def
run_private; run; print " privée"; end
protected
def
run_protect; run; print " protégée"; end
public
def run;
puts "je suis une
machine"; end
end
Vous pouvez placer autant de méthodes que vous le souhaitez après
chacun de ces mots-clés, vous ne devez pas le remettre avant chaque
méthode comme dans d'autres langages.
Le
Grand Mystère de la POO
s'éclaircit enfin : à présent, vous pouvez vous diriger vers les
chapitres suivants, qui contiennent toutes les connaissances de
base du Ruby que vous devez maîtriser.
Variables et constantes
L'orientation objet du langage a déjà été énoncée, voyons
maintenant comment stocker des données en Ruby : nous disposons de
variables, de constantes, de tableaux et de hachages.
Les variables
Vous pouvez associer une donnée, une information à un mot, accéder
à cette donnée et la modifier. Ce mot est appelé variable.
Lorsque vous vous apprêtez à utiliser une variable, vous devez
l'initialiser, c'est-à-dire lui associer une valeur (un chiffre,
une chaîne de caractères, etc.), sans quoi elle se verra assigner
la valeur nil (null dans d'autres langages, absence de valeur)
par défaut (sauf pour les variables locales que nous verrons plus
bas). Voici un exemple :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
nom = "Aristote"
# une chaîne de caractères
-
annee = 2006 # un nombre
-
langage = "Ruby"
-
bool = true
-
-
puts "#{nom} apprend le #{langage} en #{annee}"
Un nom de variable ne doit surtout pas débuter par un chiffre ou contenir
d'accents !
Ce code produit :
Code : Console - Afficher / masquer les numéros de
ligne
Aristote apprend le Ruby en 2006
En effet, #{variable} est remplacé
(lorsqu'il est placé entre guillemets) par la valeur de la variable
en question : ici #{nom} est remplacé
par "Aristote".
Récupérer une saisie au clavier
puts et print, que nous avons déjà rencontrées plus tôt,
sont des méthodes capables d'afficher une chaîne de caractères sur
la sortie standard (console).
Pour effectuer l'opération inverse, c'est-à-dire saisir une chaîne
de caractères sur l'entrée standard (lorsque vous tapez quelque
chose au clavier), utilisez la méthode gets et placez ce qu'elle reçoit dans une
variable :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
puts "votre nom ?"
-
nom = gets
-
puts "votre nom est #{nom}"
Ce que vous avez saisi au clavier avant d'appuyer sur la touche
Entrée est désigné par gets, cette instruction : nom = gets place cette saisie dans la variable
nom.
Fermons cette parenthèse et revenons à nos variables : par
définition, la valeur d'une variable peut varier au court du
programme, il en existe 4 types.
Les variables globales
Les variables globales sont des variables dont la valeur est
accessible n'importe où dans le programme. Leur nom commence par le
symbole $.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
$glob = 4
-
-
class Ordinateur
-
def initialize
-
puts $glob
# accessible ici
-
end
-
end
-
-
def methode
-
puts $glob # ici aussi
-
end
-
-
monOrdi = Ordinateur.new
-
methode
Quel que soit l'endroit où on déclare $glob, on obtiendra toujours :
Code : Console - Afficher / masquer les numéros de
ligne
Il existe quelques variables globales dont le nom est réservé ; en
voici quelques unes (utiles pour suivre le cheminement d'un script
ou pour localiser des erreurs) :
- $_ désigne la dernière chaîne lue
par gets
- $@ désigne le lieu de l'erreur
(le cas échéant)
- $. désigne la dernière ligne lue
par l'interpréteur
- $* désigne les arguments de la
ligne de commande.
Les variables locales
Un nom de variable locale débute par une lettre minuscule (comme
toutes les variables que nous avons utilisées dans nos exemples
jusque là) ou par un tiret underscore
_ : monOrdi et _tonOrdi
sont des noms de variables locales corrects.
Par défaut, les variables sont locales. Leur portée est limitée au
bloc dans lequel elles sont déclarées ; ça peut être à l'intérieur
d'une classe, d'une méthode, d'une boucle, d'une condition ou
l'ensemble du programme :
- une variable locale déclarée dans un bloc n'est pas définie en
dehors
- une variable locale déclarée en dehors de tout bloc n'est pas
définie à l'intérieur des blocs.
Contrairement aux variables globales, elles ne possèdent pas la
valeur nil avant initialisation.
Si vous ne savez pas quel type de
variable utiliser, utilisez une variable locale.
Les variables d'instance
Ces variables ne sont accessibles que depuis une classe. Il est
aussi à noter que deux objets de la même classe peuvent avoir des
mêmes variables d'instance mais dont la valeur diffère. Elles sont
donc spécifiques à une instance d'une classe donnée. Leur nom
commence par le symbole @.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Ordinateur
-
def initialize(prix)
-
@prix = prix
-
end
-
end
-
-
monOrdi = Ordinateur.new(799)
-
tonOrdi = Ordinateur.new(829)
@prix est une variable d'instance de
la classe Ordinateur, elle vaut 799
pour l'instance monOrdi et 829 pour
l'instance tonOrdi.
Les variables de classe
Ces variables contiennent une information stockée dans la classe
elle-même, et non dans les objets instanciés par cette classe ; en
outre, cette information s'applique à toutes les instances créées
par cette classe. Le nom de ces variables commence par @@.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Ordinateur
-
@@annee = 2007
-
def initialize
-
puts @@annee
-
end
-
end
-
-
monOrdi = Ordinateur.new
-
tonOrdi = Ordinateur.new
Dans notre exemple, @@annee est une
variable de classe ; les deux instances monOrdi et tonOrdi
ont cette variable de classe en commun car ce sont des instances de
la même classe Ordinateur.
Les constantes
Les constantes remplissent la même
fonction que les variables, à la seule différence que vous ne devez pas modifier leur valeur au long du
programme. Si vous le faites, vous n'obtiendrez pas d'erreur, mais
un simple avertissement.
Le nom d'une constante débute par une majuscule, vous pouvez
également les écrire intégralement en majuscule, pour les repérer
plus facilement :
Code : Ruby
PRIX = 789
puts PRIX
Vous pouvez également créer des constantes
de classe, elles sont déclarées au sein d'une classe et ne
peuvent pas être modifiées :
Code : Ruby
class
Ordinateur
PRIX = 699
def
initialize
puts PRIX
end
end
monOrdi = Ordinateur.new
Au chapitre suivant, vous verrez comment stocker des données dans
des tableaux et des hachages.
Tableaux et hachages
Vous connaissez les variables et les constantes ? Maintenant, place
aux tableaux et aux hachages qui vous permettent également de
stocker des données.
Les tableaux
Un tableau est une structure pouvant
stocker des données. Des données de types différents peuvent
cohabiter dans un même tableau (par exemple, un nombre et une
chaîne de caractères). Un tableau est délimité par des crochets et
ses éléments sont séparés par des virgules.
Code : Ruby
prix = [30, 400, 25, 73] #
tableau contenant des entiers
puts prix # affichage de
toutes les valeurs du tableau
langues = ["fr",
"en"]
# tableau de chaînes de caractères
puts langues
mix = 4, "quatre"
# tableau mixte
puts mix
et on obtient :
Code : Console
30
400
25
73
fr
en
4
quatre
Les crochets ne sont pas obligatoires, quel que soit le type des
éléments contenus dans le tableau.
Chaque élément du tableau est associé à un chiffre (un entier
naturel pour être exact) qui représente la case du tableau qu'il
occupe, la première case correspond à l'indice 0. Un exemple pour
vous éclairer :
Code : Ruby
prix = [30, 400, 25, 73]
puts prix[0]
puts prix[2],
prix[3]
On obtient :
Code : Console
30
25
73
prix[0] correspond au premier élément
du tableau, ce tableau contient 4 éléments donc 3 est l'indice du
dernier élément, désigné par prix[3].
Les hachages
Les hachages sont des tableaux
particuliers, au lieu d'associer une valeur à son indice (la place
qu'elle occupe dans le tableau), elle sera associée à une clé (un
mot). Voilà qui devrait vous parler davantage :
Code : Ruby
livre = {
"titre" =>
"Toto perd la tête",
"auteur" =>
"Toto",
"sujet" =>
"La vie de Toto"
}
Dans le hachage livre, "Toto" est associé à la clé "auteur", cette valeur est désignée par
livre["auteur"] :
Code : Ruby
puts
livre["auteur"]
On obtient :
Code : Console
Toto
Si on avait eu recours à un tableau, on aurait utilisé livre[1] pour désigner "Toto". La seconde différence essentielle avec
les tableaux ordinaires est l'utilisation d'accolades dans la
déclaration des éléments à la place de crochets. Vérifiez que vous
ne vous êtes pas trompés en cas d'erreur inexpliquée (les accolades ne sont pas
facultatives).
Quand utiliser un hachage plutôt qu'un
tableau ?
Lorsque les données sont du mêmes type, et qu'elles appartiennent à
un même ensemble (par exemple : la suite des nombres premiers
jusqu'à 1000, la liste des prénoms de vos amis, etc.) un tableau
est plus indiqué. Dans tous les autres cas, un hachage conviendrait
mieux.
Typage dynamique
Ruby n'est pas un langage à typage
statique comme le C, vous n'avez pas besoin de préciser de
quel type sont vos données avant de pouvoir les utiliser.
Le typage dynamique vous permet par
exemple de changer le type d'une variable (c'est le transtypage) au cours du programme :
Code : Ruby
a = 4
puts a
a = "hello"
puts a
a = 7, "lalala",
14
puts a
a = false
puts a
Ce code est tout à fait correct, il faut juste vous assurer que les
méthodes que vous invoquerez sur a
sont définies pour le type de données qu'elle contient.
Le prochain chapitre est consacré aux opérateurs.
Les opérateurs
Les opérateurs + * - / ** % sont des
méthodes. Les objets auxquels ils sont liés sont les objets des
classes Integer, Float et String.
Voyons ce qu'il est possible de faire avec ces méthodes.
Opérations arithmétiques
Ces 6 opérateurs définissent 6 opérations arithmétiques :
- l'addition : a + b
- la soustraction : a - b
- la multiplication : a * b
- la division : a / b
- le modulo : a % b est le reste de
la division euclidienne de a par
b, c'est à dire que a, b et
r = a % b sont des entiers
- la mise en exposant : a ** 3 = a * a *
a
Ces opérations vous permettent de manipuler deux sortes de nombres
: les entiers et les décimaux (ou flottants). L'utilisation de
parenthèses permet de modifier l'ordre de priorité entre ces
opérations. En effet :
Code : Ruby
puts 2 * 3 + 5 ** 2
puts (2 * (3 + 5))
** 2
On obtient :
Code : Console
31
256
La notation scientifique est aussi tolérée : 1,8.10^4 s'écrit 1.8e4 (à ne pas confondre avec la notation
exponentielle, mais c'est une autre histoire ).
Simplifications
Il peut nous arriver d'écrire une expression comme :
Code : Ruby
i = i + 1
Ceci nous amène à citer deux fois la même variable dans la même
expression, Ruby nous permet de remplacer ceci par :
Code : Ruby
i += 1
# on ajoute 1 à la valeur de i
Le fait d'ajouter une valeur constante (ici 1) à une variable
s'appelle l'incrémentation, si on
retranche une valeur constante, on parle de décrémentation.
Dans certains langages, on peut
simplifier l'expression i += 1 pour
obtenir i++, de même avec
l'expression i -= 1 pour obtenir
i--. Ceci n'est (malheureusement)
pas possible en Ruby !
Il est possible de simplifier toutes les opérations arithmétiques
de base vues jusque là :
Addition
Code : Ruby
i = i + 8
# se simplifie en
i += 8
Soustraction
Code : Ruby
n = n - 3
# se simplifie en
n -= 3
Multiplication
Code : Ruby
z = z * 9
# se simplifie en
z *= 9
Division
Code : Ruby
f = f / 5
# se simplifie en
f /= 5
Modulo
Code : Ruby
k = k % 7
# se simplifie en
k %= 7
Exposant
Code : Ruby
v = v ** 6
# se simplifie en
v **=6
Opérations sur les chaînes de
caractères
L'opérateur d'addition et celui de multiplication permettent
également de manipuler des chaînes de caractères. Par exemple, ce
code :
Code : Ruby
puts "hello" + " world !"
a pour résultat :
Code : Console
hello world !
Les deux chaînes de caractères ont été mises bout à bout
(concaténées). On peut également
mettre le résultat de la concaténation dans une variable :
Code : Ruby
text = "hello" +
" world !"
puts text
On obtiendra le même résultat.
Ce code-ci :
Code : Ruby
puts "zog ! " * 4
produit comme on s'y attendrait :
Code : Console
zog ! zog ! zog ! zog !
Cela se passe de commentaires, non ?
Simplifications
Ces simplifications se basent sur le même modèle que pour les
opérations arithmétiques.
Multiplication
Code : Ruby
text = "ruby" *
3
# peut s'écrire
text = "ruby"
text *= 3
Concaténation
Code : Ruby
phrase = "site"
phrase = phrase + " du zero"
# peut s'écrire
phrase = "site"
phrase += " du zero"
# ou encore
phrase = "site"
phrase << " du zero"
Au prochain chapitre, un TP pour se dégourdir les
jambes doigts.
TP : Convertisseur monétaire
Pour ce premier TP, je vous propose de coder un convertisseur
monétaire. Oui je sais ça peut se trouver dans le commerce pour pas
cher, mais c'est plus drôle si on le fait nous-même. Il n'y a rien de
révolutionnaire, mais c'est un bon début pour vous faire la
main.
Nous utiliserons simplement des fonctionnalités de base du langage
Ruby, si vous avez lu les chapitres précédents, vous en savez
largement assez pour en venir à bout avec brio.
Énoncé
Avant de se lancer dans le code à corps perdu, définissons tout
d'abord ce que doit pouvoir faire le programme :
- instancier des objets de types : Euro, Dollar et
Franc
- convertir les Euros en Francs et en Dollars
- convertir les Dollars en Euros et en Francs
- convertir les Francs en Euros et en Dollars
Ces fonctionnalités sont très simples, par ailleurs, nous avons
choisi de ne prendre en compte que trois monnaies : le Dollar,
l'Euro et le Franc Français (anciennement). Nous aurions très bien
pu prendre le Yen, le Dinar, le Louis d'Or, le Deutsche Mark ou que
sais-je encore...
Dans un premier temps, écrivons trois classes : une nommée
Franc, une autre Dollar et une dernière Euro.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Euro
-
#
-
end
-
-
class Dollar
-
#
-
end
-
-
class Franc
-
#
-
end
Chacune de ces classes sera capable d'initialiser une variable
nommée @montant en fonction du
paramètre qu'elle recevra lors de la création d'un objet. Elles
disposeront également de deux méthodes pour convertir la valeur de
leur objet dans les deux autres monnaies.
Voici les taux de conversion de ces monnaies (à l'heure où j'écris
ces lignes) :
1 E = $ 1.27175
1 E = 6.55957 F
$ 1 = 0.78632 E
$ 1 = 5.15792 F
1 F = 0.152449 E
1 F = $ 0.193877
Voilà, vous avez toutes les clés en main, dépêchez vous de coder
avant la correction, le programme est très court !
Correction
Voici le code brut, les noms de classes, de variables et de
méthodes sont suffisamment explicites pour qu'on puisse se
permettre de se passer de commentaires :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Euro
-
def initialize(montant)
-
@montant = montant
-
end
-
def en_dollars # 1 E = $
1.27175
-
puts "#{@montant}
E = $ #{@montant * 1.27175}"
-
end
-
def en_francs # 1 E = 6.55957
F
-
puts "#{@montant}
E = #{@montant * 6.55957} F"
-
end
-
end
-
-
class Dollar
-
def initialize(montant)
-
@montant = montant
-
end
-
def en_euros # $ 1 = 0.78632
E
-
puts "$
#{@montant} = #{@montant * 0.78632} E"
-
end
-
def en_francs # $ 1 = 5.15792
F
-
puts "$
#{@montant} = #{@montant * 5.15792} F"
-
end
-
end
-
-
class Franc
-
def initialize(montant)
-
@montant = montant
-
end
-
def en_euros # 1 F = 0.152449
E
-
puts "#{@montant}
F = #{@montant * 0.152449} E"
-
end
-
def en_dollars # 1 F = $
0.193877
-
puts "#{@montant}
F = $ #{@montant * 0.193877}"
-
end
-
end
Chaque classe fonctionne comme cela a été prévu dans l'énoncé :
instanciez un nouvel objet (de type Euro ou Dollar ou
Franc), puis appelez une des deux
méthodes de cet objet afin d'effectuer la conversion. Par exemple
:
Code : Ruby - Afficher / masquer les numéros de
ligne
-
argentDePoche = Euro.new(5) #
@montant sera égal à 5
-
argentDePoche.en_francs
Normalement, ce code ne contient aucun élément obscur, tout ce qui
a été utilisé a déjà été abordé dans les chapitres précédents.
Maintenant que vous avez vu si votre programme fonctionnait ou non
(et que vous l'avez éventuellement corrigé), voyons comment
l'optimiser.
Nos trois classes Dollar,
Euro et Franc possèdent une même méthode d'initialisation
identique : pour un programmeur, c'est une perte de temps d'écrire
trois fois un même code, nous allons donc voir comment y remédier !
Nous avons besoin de "quelque chose" pouvant disposer de la méthode
initialize et capable de la
redistribuer aux classes Dollar,
Euro et Franc. Nous utiliserons donc une super-classe que
nous nommerons Monnaie, et dont les
trois autres classes dériveront. Les trois premières classes n'ont
pas besoin de redéfinir la méthode initialize de la classe Monnaie.
Ce code montre comment intégrer cette nouvelle classe :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Monnaie
-
def initialize(montant)
-
@montant = montant
-
end
-
end
-
-
class Euro <
Monnaie
-
def en_dollars
-
puts "#{@montant}
E = $ #{@montant * 1.27175}"
-
end
-
def en_francs
-
puts "#{@montant}
E = #{@montant * 6.55957} F"
-
end
-
end
-
-
class Dollar <
Monnaie
-
def en_euros
-
puts "$
#{@montant} = #{@montant * 0.78632} E"
-
end
-
def en_francs
-
puts "$
#{@montant} = #{@montant * 5.15792} F"
-
end
-
end
-
-
class Franc <
Monnaie
-
def en_euros
-
puts "#{@montant}
F = #{@montant * 0.152449} E"
-
end
-
def en_dollars
-
puts "#{@montant}
F = $ #{@montant * 0.193877}"
-
end
-
end
Vous pouvez lancer ce programme de la même manière que pour le
précédent.
N'hésitez pas à améliorer ce court programme si vous avez des
idées.
Au cours des prochains chapitres, vous verrez les instructions de
contrôle, et on en aura fini avec les bases du langage.
Les conditions
Jusque là, nos programmes étaient monotones, linéaires, ils
fonctionnaient toujours de la même façon.
Or, dans la plupart des cas, on a besoin d'adapter le déroulement
du programme en fonction de certains paramètres (une action de
l'utilisateur, etc.). Voilà pourquoi on peut avoir recours aux
structures conditionnelles.
La condition if - else
La structure en if - else est la plus
simple des structures conditionnelles. Elle évalue une expression,
si (if) cette condition est remplie,
certaines instructions sont exécutées, sinon (else) on en exécute d'autres. Comme l'illustre
cet exemple :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
age = 17
-
-
if(age >= 18)
-
puts "vous etes majeur"
-
else
-
puts "vous etes mineur"
-
end
On obtient :
Code : Console - Afficher / masquer les numéros de
ligne
Les parenthèses entre lesquelles se situe la condition sont
facultatives. Vous pouvez modifier la valeur de age pour voir le résultat obtenu.
Si la condition entre parenthèses est
vérifiée, l'état true lui est assigné
: le cas échéant, ce sera la valeur false. Comme nous l'avons déjà vu, vous pouvez
aussi assigner ces valeurs booléennes à des variables.
Il existe un mot-clé facultatif,
then, améliorant la lisibilité de la
condition (enfin, c'est mon avis, hein ) :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
age = 17
-
-
if age >= 18
-
then puts "vous etes majeur"
-
else puts "vous etes mineur"
-
end
Afin de tester ce genre d'expression arithmétique, vous disposez
des opérateurs suivants :
- == vérifie l'égalité du
premier terme par rapport au second (à ne pas confondre avec le
symbole d'égalité simple = qui sert à
l'affectation de valeurs)
- < vérifie que le premier
terme est strictement inférieur au second
- > vérifie que le premier
terme est strictement supérieur au second
- <= vérifie que le premier
terme est inférieur ou égal au second
- >= vérifie que le premier
terme est supérieur ou égal au second
- != vérifie l'inégalité du
premier terme par rapport au second
Nous ne sommes pas obligés de placer un else dans la condition ; par exemple, ceci
fonctionne (avec ou sans le then)
:
Code : Ruby - Afficher / masquer les numéros de
ligne
-
age = 17
-
-
if age < 18
-
puts "vous etes mineur"
-
end
Et on obtient sans surprise :
Code : Console - Afficher / masquer les numéros de
ligne
Une structure conditionnelle se termine par le mot-clé end. Celui-ci se situe après la dernière
condition (après le else, sinon après
le if).
Si une condition est vérifiée, l'état
true (vrai) lui est assigné ; le cas
échéant, ce sera la valeur false. Ces
deux mots-clés sont ce qu'on appelle des valeurs booléennes, vous pouvez aussi les
assigner à des variables.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
estMajeur = false
-
-
if (estMajeur)
-
then puts "Vous etes majeur"
-
else puts "Vous etes mineur"
-
end
La valeur true se déduit d'elle-même
: vous n'avez pas besoin d'écrire if(estMajeur == true). Pour tester la valeur
false, on aurait pu écrire
if(estMajeur == false), mais ceci
fonctionne aussi : if!(estMajeur).
Il existe une autre façon d'utiliser la condition if :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
puts "vous etes majeur" if(estMajeur)
Dans ce cas, l'instruction à exécuter doit être la seule ; on ne
s'encombre pas d'un end final.
Condition alternative : elsif
La condition vue précédemment peut être enrichie davantage, des
choix intermédiaires peuvent être proposés, par test de plusieurs
conditions successives (si.. sinon si..
sinon si.. sinon). La première condition vérifiée comme
étant vraie sera exécutée, les autres seront alors ignorées (même
si elles sont vraies elles aussi).
Code : Ruby
a = 5
b = 4
c = 7
if (a <
b) # false
#
elsif (a <
c) # true
#
elsif (b <
c) # true
#
else
#
end
(a < b) est fausse, les
instructions suivant le if ne sont
donc pas exécutées.
(a < c) est vraie, donc les
instructions suivant le premier elsif
sont exécutées, on sort ensuite de la structure conditionnelle.
Les instructions de second elsif et
du else ne sont pas exécutées, même
si (b < c) est vraie.
Vous pouvez mettre autant de
elsif que vous voulez.
Les autres remarques faites précédemment sont encore valables ici.
La condition unless
unless est la condition contraire de
if. Elle exécute une instruction
sauf si la condition est vérifiée.
Par exemple :
Code : Ruby
unless
1>3
# condition fausse donc exécutée
puts
"ok"
end
On obtient :
Code : Console
ok
unless(estMajeur) effectue la même
chose que if!(estMajeur), vous pouvez
donc utiliser la condition que vous préférez.
Tout comme l'instruction if, il est
possible d'écrire :
Code : Ruby
puts "vous etes mineur" unless(estMajeur)
L'instruction case
Cette instruction teste une suite de conditions : elle évalue
plusieurs cas et exécute certaines instructions en conséquence (la
première condition vérifiée masque les autres comme dans les
structures en if). Voici comment
l'utiliser :
Code : Ruby
z = 4
case z
when
1 # dans le cas où z =
1
print "z = 1"
when
"maison" # dans le cas
ou z contient la chaîne "maison"
print "z =
'maison'"
when z =
2
when z =
3
when z =
4
print "z = 4"
when z =
5
end
On obtient :
Code : Console
z = 4
On teste ici différents cas en fonction de la valeur de
z. when
1 équivaut implicitement à when z =
1. Cette structure case se
termine là aussi par un end.
Il est également possible de tester si une variable donnée
appartient à un certain intervalle, nous verrons comment faire ceci
lors de l'étude de la boucle for.
Condition ternaire
Il existe encore une autre solution pour évaluer une expression
booléenne, elle fonctionne suivant ce schéma :
condition ? (si vrai) :
(sinon)
Un exemple :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
a = 4
-
b = 7
-
-
(a < b) ? (puts "a < b") : (puts "a > b")
On obtient :
Code : Console - Afficher / masquer les numéros de
ligne
En effet, a est inférieur à
b, donc a <
b est vraie et l'expression à gauche des deux-points est
exécutée ; si a < b avait eu la
valeur false, on aurait exécuté
l'expression à la droite des deux-points.
Associations de conditions
Si votre programme a un comportement complexe basé sur des
combinaisons de conditions, il se peut que vous ayez à écrire
quelque chose de ce genre :
Code : Ruby
if(a < b)
if(b > c)
#
end
end
Il existe un moyen de simplifier ce genre de condition multiple, on
peut tester deux conditions (ou plus) à la fois de cette manière
:
Code : Ruby
if(a < b && b > c)
#
end
(a < b && b > c) vaut
true si (a
< b) et (b > c) sont
vraies en même temps.
On peut aussi s'assurer qu'au moins une des conditions est vérifiée
:
Code : Ruby
if(a < b || c > a)
#
end
Ici, il suffit que (a < b) ou
(c > a) soit vraie (ou les deux)
pour que (a < b || c > a) soit
vraie.
Vous pouvez modifier l'ordre des priorités en regroupant certaines
conditions entre parenthèses, comme pour les opérations
arithmétiques.
Pour améliorer la lisibilité du code, il est possible de remplacer
&& par le mot-clé
and et || par or.
La suite des instructions de contrôle vous attend au chapitre
suivant, lequel abordera les boucles.
Les boucles
Les boucles sont utilisées dans l'objectif de répéter une
instruction donnée un certain nombre de fois. Là aussi, il existe
plusieurs manières d'accomplir la même chose.
La boucle while
La boucle while équivaut à un
if qui se répète tant qu'une certaine condition est considérée
comme true.
La condition que vous placez entre les parenthèses (facultatives)
est de même type que celles des conditions if, unless,
etc.
Code : Ruby
a = 2
b = 5
while (a <
b)
puts
"a < b"
end
Ici, la condition est toujours vraie, la boucle se répétera alors à
l'infini. Donc dans une boucle while,
on modifie la valeur d'une donnée prise en compte dans la
condition, qui est ici un nombre, mais qui pourrait aussi bien être
une valeur booléenne :
Code : Ruby
estConnecte = true
while(estConnecte)
puts
"vous etes connecte"
estConnecte = false
end
puts "vous avez ete
deconnecte"
La valeur de estConnecte est mise à
false dès le premier tour de boucle,
ainsi la condition du while n'est
plus vérifiée et la boucle n'est plus parcourue, on obtient donc
:
Code : Console
vous etes connecte
vous avez ete deconnecte
On peut régler l'exécution d'une boucle while en utilisant un compteur et ainsi exécuter
une instruction un certain nombre de fois. Voici comment procéder
:
Code : Ruby
var = 0
while (var <=
4)
print var
var += 1
end
La valeur de var augmente de 1 à
chaque tour de boucle, lorsqu'elle atteint 5, la boucle n'est plus
parcourue, on obtient :
Code : Console
01234
Il est possible de réécrire cette boucle en mettant la condition à
la fin :
Code : Ruby
begin
print var
var += 1
end while
(var <= 4)
Cette boucle, délimitée par begin et
end while, est toujours exécutée au
moins une fois, la condition n'est évaluée qu'après le premier tour
de boucle.
Ici, cette boucle nous fournit le même résultat.
La boucle loop
La boucle loop est infinie, et ne
prend donc pas de condition en paramètre, elle équivaut à une
boucle while(true). Étant donné
qu'elle est infinie, il vous faudra l'instruction break pour en sortir.
Code : Ruby
n = 0
loop {
print n
n += 2
break
if (n >
6)
}
La boucle est parcourue jusqu'à ce que n soit supérieur à 6, on obtient donc :
Code : Console
0246
Les accolades {} peuvent être
remplacées par les mots-clés do et
end, ainsi cette notation est
correcte :
Code : Ruby
loop do
print n
n += 2
break
if (n >
6)
end
La boucle until
La boucle until est à la boucle
while ce que unless est à if.
Cette boucle
s'exécute jusqu'à ce qu'une condition soit vraie. Elle est donc
totalement équivalente à while!(condition), voici un exemple :
Code : Ruby
n = 0
until n>5
print n
n += 2
end
La boucle est parcourue jusqu'à ce que n soit supérieur à 5, ainsi
on obtient :
Code : Console
024
Tout comme la boucle while, on peut
réécrire cette boucle de cette manière :
Code : Ruby
begin
print n
n += 2
end until
n>5
Les instructions placées entre begin
et end until seront exécutées au
moins une fois car la condition n'est évaluée qu'après le premier
tour de boucle.
La boucle for
La boucle for est quelque peu
différente de la précédente : elle exécute une instruction donnée
pour chaque élément d'un ensemble, par exemple pour obtenir la
liste de tous les nombres de l'ensemble [O;
7], il nous faut écrire :
Code : Ruby
for n in (0..7)
print n
end
print n est exécutée pour chaque
élément de [0; 7], n prend successivement les valeurs de cet
ensemble, nous obtenons donc :
Code : Console
01234567
Une boucle for se termine par un
end.
La notation t..n désigne les éléments compris dans
l'intervalle délimité par t et
n où t
et n sont des nombres et sont
considérés comme étant inclus dans cet intervalle.
La notation t...n désigne le même
ensemble, à la différence que la seconde borne de l'ensemble est
exclue, donc n n'en fait pas
partie.
Ceci est notamment utile pour les chaînes de caractères, si on
considère : sdz = "siteduzero", alors
puts sdz[0..3] affichera site, on remarque alors que la chaîne de
caractère est considérée comme un tableau (la première lettre porte
l'indice 0).
Il est tout à fait possible de mettre en association plusieurs
conditions et plusieurs boucles : les enchaîner, les emboîter,
etc., du moment que vous respectez l'ordre des
end sans vous mélanger les pinceaux !
Les itérateurs
Les itérateurs permettent d'accéder,
tout comme la boucle for, à tous les
éléments d'un ensemble un à un. Cet
ensemble peut être délimité par des nombres comme nous l'avons vu
lors de l'étude de la boucle for,
mais aussi un tableau ou un hachage.
Chaque exemple d'itérateur sera mis en parallèle avec une boucle
for, vous pourrez donc utiliser la
construction que vous préférez.
Parcourir des nombres
Pour chaque nombre d'un ensemble
Comme nous l'avons vu dans le chapitre précédent, une boucle
for permet de parcourir un ensemble
de nombres de la manière la plus simple qui soit, par exemple :
Code : Ruby - Afficher / masquer les numéros de
ligne
n prend successivement la valeur de
2, 3, 4, 5, 6 et 7.
Il est possible de réécrire cette boucle à l'aide d'une méthode :
upto (Integer#upto). Cette méthode de la classe
Integer s'applique à un entier, elle
l'incrémente et exécute un bloc d'instructions jusqu'à atteindre le
nombre passé en paramètre. Voici un exemple permettant d'obtenir la
même chose que la boucle du dessus :
Code : Ruby - Afficher / masquer les numéros de
ligne
Le bloc |x| puts x, délimité par des
accolades est exécuté 6 fois, x prend
successivement les valeurs 2, 3, 4, 5, 6 et 7. Le nom de la
variable, ici x, est mis entre deux
barres et peut être changé. Le bloc de code peut être délimité par
les mots-clés do et end et peut contenir autant d'instructions que
vous le voulez :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
2.upto(7) do |var|
-
puts var
-
end
Il existe une méthode permettant de faire la même chose à l'envers
: downto (Integer#downto) :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
7.downto(2) {
|x| puts x }
x prend les valeurs 7, 6, 5, 4, 3 et
2. Les remarques faites plus haut sont valables ici aussi.
Un certain nombre de fois
Nous pouvons exécuter un bloc de code un certain nombre de fois,
c'est ce que nous permet la méthode times (Integer#times). Elle s'applique à un entier et
exécute le bloc qu'on lui fournit autant de fois ; voici un exemple
:
Code : Ruby - Afficher / masquer les numéros de
ligne
Ainsi, l'instruction puts x est
exécutée 2 fois (times est appelée
sur l'entier 2). L'itération commençant à 0, x prend successivement les valeurs 0 et 1. Nous
obtenons donc :
Code : Console - Afficher / masquer les numéros de
ligne
Pour obtenir la même chose avec une boucle for, il nous faut écrire :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
for x in 0...2
-
puts x
-
end
Parcourir un tableau
Nous disposons de la méthode each
(Array#each) qui exécute un bloc
d'instructions pour chaque élément du tableau sur lequel on
l'invoque. Considérons ce tableau :
Code : Ruby
array =
["zero",
"un", "deux"]
Nous utilisons each de cette manière
:
Code : Ruby
array.each { |n| puts n }
Le fonctionnement est le même que celui de times : n prend
successivement les valeurs des éléments du tableau array, à savoir zero, un et
deux ; puts
n est exécuté pour chaque valeur de n. Nous obtenons donc :
Code : Ruby
zero
un
deux
Voici l'équivalent avec une boucle for, tout aussi simple :
Code : Ruby
for n in array
puts n
end
Parcourir une chaîne de caractères
Une chaîne de caractères peut être considérée comme un tableau et
peut donc être parcourue tout aussi simplement. Considérons cette
chaîne de caractères :
Code : Ruby
chaine = "Bonjour !
Comment allez-vous ?"
Le saut de ligne peut être remplacé par \n, qui ne compte que pour un seul caractère,
ainsi, notre chaîne équivaut à :
Code : Ruby
chaine = "Bonjour
!\nComment allez-vous ?"
La classe String dispose, tout comme
la classe Array, d'une méthode
each (String#each) permettant de parcourir les chaînes
de caractères, le fonctionnement est similaire à celui de
Array#each :
Code : Ruby
chaine.each
{ |l| puts l
}
puts l est exécuté pour chaque
portion de la chaîne sur laquelle on l'appelle. Nous obtenons :
Code : Console
Bonjour !
Comment allez-vous ?
La chaîne a donc été découpée suivant les sauts de ligne ; en
effet, la méthode String#each peut
prendre en argument un caractère afin de délimiter les portions de
chaînes, par défaut ce caractère est \n. Si nous voulons par exemple traiter la chaîne
mot par mot, nous précisons que le délimiteur doit être un espace
:
Code : Ruby
chaine.each(' ') { |w| puts w }
La boucle for nous permet d'obtenir
le même résultat que each sans
paramètre :
Code : Ruby
for n in chaine
puts n
end
Une chaîne de caractères est en fait un tableau d'octets. Vous
disposez d'une autre méthode, each_byte (String#each_byte) qui vous permet de traiter une
chaîne octet par octet. Voici comment traiter une chaîne caractère
par caractère, après une conversion à l'aide de la méthode
chr :
Code : Ruby
chaine.each_byte
{ |c| puts
c.chr }
Pour ne pas entrer dans les détails, souvenez-vous seulement que
c.chr désigne successivement chaque
caractère de la chaîne sur laquelle est invoquée la méthode
each_byte.
Parcourir un hachage
Parcourir un hachage se fait (quasiment) de la même manière que
pour un tableau : à l'aide de la méthode each de la classe Hash (Hash#each).
Considérons ce hachage :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
hash = { "un" => 1, "deux" => 2 }
Pour parcourir les paires clés-valeurs du hachage, nous procédons
comme suit :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
hash.each { |k, v| puts "#{k} => #{v}" }
k et v
(on utilise plus généralement key et
value), séparés par une virgule,
représentent successivement les clés et les valeurs associées du
hachage sur lequel est appelée la méthode each. Quand k vaut
un, v
est égal à 1. Nous obtenons donc :
Code : Ruby - Afficher / masquer les numéros de
ligne
Une boucle for peut là aussi nous
permettre d'obtenir le même résultat :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
for key, value
in hash
-
puts "#{key} =>
#{value}"
-
end
Nous verrons un peu plus tard comment créer nous-mêmes des
itérateurs.
Ce chapitre met fin aux bases du langage, les choses sérieuses vont
maintenant pouvoir commencer.
TP : Jeu des allumettes
Pour ce TP, soyons originaux ( ), je vous propose de recoder le plus ou moins
célèbre jeu des allumettes. Histoire de faire les choses
sérieusement, cet énoncé est en fait l'énoncé d'un
TD de l'École Nationale Supérieure des Télécommunications
(ENST), datant de
Novembre 2005.
Le programme devait être codé en langage C. Ceci n'étant pas le but
de ce tuto, j'ai adapté les consignes de développement au langage
qui nous intéresse ici, à savoir le Ruby. Ce TP réclame peut-être
un peu plus de réflexion que le précédent, mais il n'y a pas de
quoi fouetter un chat. Le sérieux de l'énoncé ne doit pas vous
intimider, le sujet est en fait très simple, comme en témoignera
une des corrections possibles fournie à la fin du TP.
Bon code !
Énoncé
Introduction
Le jeu des allumettes (encore appelé jeu de
nim) se joue à deux. Les deux joueurs se
partagent un tas de 21 allumettes. À tour de rôle,
ils doivent retirer 1, 2 ou 3 allumettes du tas ;
le joueur qui retire la dernière allumette a perdu. Le but de ce
mini projet est de vous faire réaliser un jeu des allumettes en
Ruby. Votre programme devra permettre à un joueur humain
d'affronter l'ordinateur.
Consignes de développement
Le tas d'allumettes sera représenté par un entier. Votre programme
devra comporter une boucle principale qui s'arrêtera lorsque le tas
sera vide.
Vous définirez deux fonctions :
- joueur_humain(tas)
- joueur_ordinateur(tas)
Elles renverront le nombre d'allumettes à retirer du tas. Le
paramètre tas permettra aux joueurs
de connaître le nombre d'allumettes présentes dans le tas.
Typiquement, la fonction joueur_humain affichera à l'écran le nombre
d'allumettes dans le tas et demandera à l'utilisateur de saisir le
nombre d'allumettes qu'il souhaite retirer.
La fonction joueur_ordinateur
implémentera une intelligence artificielle. L'intelligence
artificielle n'a pas besoin d'être compliquée ; la fonction peut
par exemple choisir un nombre aléatoire entre 1 et 3 (tout en étant
inférieur à tas).
Votre programme devra désigner arbitrairement le joueur qui doit
commencer. À chaque tour de boucle, votre programme appellera les
fonctions joueur_humain et
joueur_ordinateur alternativement et
récupérera le résultat. Il faudra ensuite s'assurer de la validité
du nombre d'allumettes à retirer (entre 1 et 3, inférieur à
tas). Il faudra ensuite afficher
l'état du jeu, c'est-à-dire le nombre d'allumettes restant.
À la fin de la partie, le programme devra afficher le numéro du
joueur gagnant.
Aide
La fonction rand (Kernel#rand), appelée avec n pour argument renvoie un nombre aléatoirement
choisi entre 0 et n-1.
Travail à réaliser
L'interface de votre programme utilisera la ligne de commande
(puts, etc.). Vous êtes libre de
programmer une intelligence évoluée. Mais n'y passez pas trop de
temps tout de même. Un programme qui s'exécute correctement malgré
une intelligence artificielle simpliste rapportera plus de
points mérite qu'un programme buggé doté
d'une intelligence artificielle élaborée...
Échéances
Vous devrez rendre votre travail le 7 décembre
(la journée se termine à minuit) à votre encadrant de TD.
Prenez votre temps.
Correction
Le code détaillé
La méthode
joueur_humain
Citation : Enoncé
Typiquement, la fonction joueur_humain affichera à l'écran le nombre
d'allumettes dans le tas et demandera à l'utilisateur de saisir le
nombre d'allumettes qu'il souhaite retirer.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
def
joueur_humain(tas)
-
puts "Il y a #{tas} allumettes sur
le tas."
-
puts "Retirer combien d'allumettes
?"
-
saisie = gets.to_i
-
saisie =
joueur_humain(tas) if (saisie > tas or
![1, 2, 3].include?(saisie))
-
return saisie
-
end
Détaillons ce code :
Code : Ruby - Afficher / masquer les numéros de
ligne
On récupère la saisie de l'utilisateur (gets), on la convertit en entier (String#to_i) et on la place dans la variable
saisie.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
saisie = joueur_humain(tas) if (saisie > tas
or ![1, 2, 3].include?(saisie))
[1, 2, 3].include?(saisie) renvoie
true si saisie est inclue dans le tableau sur lequel on
appelle la méthode include?.
C'est donc équivalent à (saisie == 1 or
saisie == 2 or saisie == 3).
La condition : if (saisie > tas or ![1,
2, 3].include?(saisie)) est donc vérifiée si saisie est supérieure à tas ou est différente de 1, 2 ou 3. Dans ces
cas-là, elle est invalide, et on rappelle la fonction joueur_humain : cette fonction est dite
récursive. L'argument reste inchangé (tas), et on place ce que renvoie cette fonction
dans saisie.
Enfin, on retourne saisie.
La méthode
joueur_ordinateur
Citation : Enoncé
La fonction joueur_ordinateur implémentera une intelligence
artificielle. L'intelligence artificielle n'a pas besoin d'être
compliquée ; la fonction peut par exemple choisir un nombre
aléatoire entre 1 et 3 (tout en étant inférieur à tas).
Code : Ruby - Afficher / masquer les numéros de
ligne
-
def
joueur_ordinateur(tas)
-
if (tas == 8 or tas == 4) then choix = 3
-
elsif (tas == 7 or tas == 3) then choix = 2
-
elsif (tas == 6 or tas == 2 or tas == 1) then choix = 1
-
else choix = rand(3).succ
-
end
-
puts "L'ordinateur a enleve #{choix}
allumettes."
-
return choix
-
end
Cette fonction est plus simple à comprendre. L'intelligence
artificielle ( )
repose sur une astuce : laisser 5 allumettes au joueur adverse ; en
effet :
- s'il en prend 1, il en reste 4, vous en
prenez 3, il en reste 1, vous gagnez ;
- s'il en prend 2, il en reste 3, vous en
prenez 2, il en reste 1, vous gagnez ;
- s'il en prend 3, il en reste 2, vous en
prenez 1, il en reste 1, vous gagnez.
Les expressions mises en rouge illustrent les conditions (sur la
deuxième colonne) de la fonction.
Pour en laisser 5 à l'utilisateur :
- s'il en reste 8, vous en prenez 3,
- s'il en reste 7, vous en prenez 2,
- s'il en reste 6, vous en prenez 1.
Et celles-ci illustrent les conditions de la première colonne de la
fonction.
De plus, s'il ne reste qu'une seule allumette, nous n'avons pas le
choix et devons la choisir.
Pour toutes les autres situations, nous choisissons un nombre
aléatoire compris entre 1 et 3 inclus. Comme précisé dans l'énoncé,
la fonction rand (Kernel#rand), appelée avec n pour argument renvoie un nombre aléatoirement
choisi entre 0 et n-1. Ainsi
rand(3) renvoie aléatoirement 0, 1 ou
2, et rand(3).succ, équivalent de
rand(3)+1 renvoie aléatoirement 1, 2
ou 3.
Étant donné le peu de contraintes concernant l'intelligence
artificielle, on pouvait très bien renvoyer un nombre aléatoire
dans tous les cas (en vérifiant bien que le nombre choisi soit
inférieur ou égal au nombre d'allumettes du tas).
Enfin, on retourne le nombre d'allumettes retirées par
l'ordinateur.
La boucle principale
Citation : Enoncé
Votre programme devra désigner
arbitrairement le joueur qui doit commencer. À chaque tour de
boucle, votre programme appellera les fonctions joueur_humain et joueur_ordinateur alternativement et récupérera
le résultat. Il faudra ensuite s'assurer de la validité du nombre
d'allumettes à retirer (entre 1 et 3, inférieur à tas). Il faudra ensuite afficher l'état du jeu,
c'est-à-dire le nombre d'allumettes restant.
À la fin de la partie, le programme devra afficher le numéro du
joueur gagnant.
Tout d'abord, définissons le nombre d'allumettes initial :
Code : Ruby - Afficher / masquer les numéros de
ligne
Puis la boucle en elle-même :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
loop {
-
tas -=
joueur_humain(tas)
-
if tas == 0
-
puts "Vous perdez
!"
-
break
-
end
-
puts "Il reste #{tas} allumettes sur
le tas."
-
tas -=
joueur_ordinateur(tas)
-
if tas == 0
-
puts "Vous gagnez
!"
-
break
-
end
-
}
On choisit (arbitrairement) de toujours faire commencer
l'utilisateur. Les fonctions joueur_humain et joueur_ordinateur sont appelées à chaque tour de
boucle. Les tests de validité du nombre d'allumettes à enlever sont
effectués dans la fonction joueur_humain ; donc, pas besoin d'encombrer la
boucle pour ça ; et si vous regardez bien, la fonction joueur_ordinateur n'en a pas besoin.
Ensuite, on affiche le nombre d'allumettes restantes : lorsqu'il
est nul, on affiche le résultat de la partie et on sort de la
boucle, mettant fin au programme.
Le code complet
Le code n'est pas commenté (je sais, c'est pas bien ), mais on vient de le
détailler :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
def
joueur_humain(tas)
-
puts "Il y a #{tas} allumettes sur
le tas."
-
puts "Retirer combien d'allumettes
?"
-
saisie = gets.to_i
-
saisie =
joueur_humain(tas) if (saisie > tas or
![1, 2, 3].include?(saisie))
-
return saisie
-
end
-
-
def
joueur_ordinateur(tas)
-
if (tas == 8 or tas == 4) then choix = 3
-
elsif (tas == 7 or tas == 3) then choix = 2
-
elsif (tas == 6 or tas == 2 or tas == 1) then choix = 1
-
else choix = rand(3).succ
-
end
-
puts "L'ordinateur a enleve #{choix}
allumettes."
-
return choix
-
end
-
-
#### boucle
principale
-
-
tas = 21
-
-
loop {
-
tas -=
joueur_humain(tas)
-
if tas == 0
-
puts "Vous
perdez!"
-
break
-
end
-
puts "Il reste #{tas} allumettes sur
le tas."
-
tas -=
joueur_ordinateur(tas)
-
if tas == 0
-
puts "Vous
gagnez!"
-
break
-
end
-
}
N'hésitez pas à améliorer ce court programme si vous avez des
idées.
J'espère que cette première partie vous a donné envie d'aller plus
loin dans votre apprentissage du Ruby. La suite du tutoriel vous
fera découvrir des aspects plus poussés du langage, ainsi que le
jeune mais néanmoins prometteur Ruby on Rails.
Partie 2 : Pratiques avancées
Pourquoi se limiter aux bases d'un langage
qui brille par sa simplicité ?
...
Ne cherchez pas, il n'y a pas de réponse.
Je vous propose donc de passer à la vitesse supérieure et d'aborder
des aspects plus poussés du langage, avec (entre autres) les bases
de données, les expressions régulières, les threads, etc. Que de
réjouissances en perspective.
Utiliser la console
Console de jeux vidéo ? Ah non, ici vous
êtes au rayon programmation !
La console vous permet de faire beaucoup de choses intéressantes,
vous avez vu qu'elle pouvait servir à lancer votre programme, à
obtenir la version de Ruby sur votre système et à vous déplacer
dans un répertoire. Mais ce n'est pas tout, elle gère également :
un interpréteur interactif, l'accès à la documentation et la
création d'une documentation pour vos propres programmes.
irb
Tapez dans un terminal :
Code : Console
irb --simple-prompt
L'argument --simple-prompt est
facultatif, il permet en outre d'utiliser la version d'irb la plus
épurée possible ; donc cette instruction fonctionne aussi :
Code : Console
irb
Ceci vous permet d'utiliser la console irb
(interactive ruby shell, c'est un
interpréteur interactif) pour tester des bouts de programmes plus
rapidement et plus simplement qu'en lançant le programme avec la
commande ruby votreprogramme.rb à
chaque modification dans le code.
Vous pouvez vous en servir notamment pour des calculs (oui ça fait
aussi calculatrice
), pour essayer certaines méthodes, pour vérifier que le passage
d'argument s'est bien déroulé, pour localiser précisément une
erreur, etc.
Voici quelques tests de bouts de code simples entrés sur
l'interpréteur :
Les lignes commençant par >>
correspondent à l'entrée (à ce que
vous tapez dans irb), tandis que
celles qui débutent par =>
correspondent à la sortie (à ce que
l'interpréteur renvoie, cela équivaut à l'instruction return que vous pouvez utiliser dans vos
programmes).
Pour quitter cet interpréteur, saisissez exit, la console reprendra alors son activité
initiale (tester vos programmes Ruby ).
Irb est pratique pour tester des bouts de code isolés, pas pour des
méthodes ou des classes codées sur plusieurs lignes ! (même si
c'est tout à fait faisable, hein !)
Accéder à la documentation
Lors de l'installation de Ruby, la documentation (de la
bibliothèque standard) était automatiquement fournie, elle est donc
à votre disposition pour que vous puissiez la consulter sans lancer
votre navigateur.
Pour y accéder, lancez la console et tapez-y la commande
ri (à la place de ruby ) suivie du nom de la classe ou de la méthode dont vous
voulez la documentation, par exemple :
Code : Console
ri Integer (doc de la classe Integer)
ri TCPSocket (doc de la classe TCPSocket)
ri TCPSocket.new (doc de la méthode new de la classe TCPSocket)
ri TCPServer#listen (doc de la méthode d'instance listen de la classe TCPServer)
C'est LE truc à savoir, à utiliser sans modération !
Pour ceux qui préfèrent lancer leur navigateur, la documentation
Ruby officielle est disponible (en Anglais) sur cette page et celle-ci.
Créer une documentation
Vous souhaitez que n'importe qui puisse
comprendre le fonctionnement de votre programme, de vos classes,
méthodes, etc. ?
La meilleure (la seule ?) solution est d'en créer une
documentation. C'est à dire un ensemble de fichiers HTML, pouvant
être consultés en ligne ou non, détaillant le fonctionnement de
votre code. Pour cela, il faut que vous commentiez votre code (en
Français, mais également en Anglais si possible).
Ensuite, en console, tapez l'instruction rdoc, il y a deux manières de faire :
Pour créer la documentation de tous vos programmes du répertoire
:
Code : Console - Afficher / masquer les numéros de
ligne
Pour choisir les programmes dont vous voulez créer une
documentation :
Code : Console - Afficher / masquer les numéros de
ligne
rdoc [fichier1] [fichier2] [etc.]
rdoc lala.rb
Cela a eu pour conséquence de créer un dossier doc dans votre répertoire, qui contient, ô
miracle, vos fichiers HTML (certains auront remarqué la présence du
fichier CSS permettant de modifier l'apparence des pages, mais ce
n'est pas le but de ce tutoriel ) dont l'architecture est la même que pour la
documentation standard : les fichiers, classes et méthodes sont
listés en haut, le détail du code apparaît au centre (avec vos
commentaires).
Les commentaires peuvent s'appliquer à ce que vous voulez : une
classe en général, mais pourquoi pas à une méthode particulière.
Vous pouvez créer une documentation pour ce code et voir par vous
même les différents emplacements possibles pour les commentaires
:
Code : Ruby - Afficher / masquer les numéros de
ligne
-
# Code de test :
-
# classe Chanteur
-
class Chanteur
-
#
initialise l'instance de la classe Chanteur
-
def initialize(nom)
-
# Paul ou Jacques ?
-
@nom = nom
-
end
-
#
définit la méthode chante de la classe Chanteur
-
def chante(chanson)
-
@chanson = chanson
-
end
-
end
-
-
# classe Chanson
-
class Chanson
-
#
initialise l'instance de la classe Chanson
-
def initialize(nom)
-
@nom = nom
-
end
-
end
Afin d'améliorer la lisibilité des pages, il vous est possible de
mettre des parties en gras, en italique et d'utiliser une police à
taille fixe (l'équivalent de la balise <pre> en html) :
Tous les commentaires qui vont suivre
devront être précédés d'un # en début
de ligne !
Pour des mots isolés :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
_italique_
-
*gras*
-
+police_fixe+
Pour des groupes de mots :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
<i> mots en italique </i>
-
<b> mots en gras </b>
-
<tt> mots à police fixe </tt>
Il est également possible de placer des titres et des sous-titres,
6 niveaux existent, les titres les plus importants sont précédés
d'un =, les moins importants de
======, la même hiérarchie existe en
HTML (de <h1> à <h6>) :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
= a
-
== a
-
=== a
-
==== a
-
===== a
-
====== a
Mais ce n'est pas tout, vous pouvez placer des listes au sein de
votre code :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
# liste à puce :
-
-
* liste à puce1
-
* liste à puce2
-
-
# liste ordonnée :
-
-
1. liste ordonnée1
-
2. liste ordonnée2
-
-
#liste de définition
:
-
-
[def1] liste de definition1
-
[def2] liste de definition2
-
-
# tableau :
-
-
Liste :: sous
-
forme :: de tableau
Sachez également qu'à l'intérieur de la documentation, à chaque
fois que vous mentionnez une classe, un fichier ou une méthode,
cette référence devient un lien pointant vers cette destination. De
plus, les URL sont automatiquement converties en liens.
Et si je veux que ma classe/méthode ne
soit pas documentée ?
Dans ce cas, il vous faut la commenter de cette manière :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class ClassCachee
# :nodoc:
-
end
-
-
def MethodeCachee
# :nodoc:
-
end
Ainsi, le code en question ne sera pas répertorié dans la
documentation.
Ce sont les principales actions pouvant être effectuées en console.
Il est possible de passer d'autres arguments en ligne de commande
(par exemple
-e,
--all, etc.), mais nous verrons cela plus tard.
Les symboles
Il se peut que vous ayez besoin d'attribuer un objet unique à une
variable (à chaque problème ses solutions, à chaque programme ses
contraintes ). Dans
certains cas il est possible d'utiliser des chiffres, des booléens
ou des chaînes de caractères, mais dans d'autres il vous faudra
utiliser des symboles, ce chapitre
est là pour vous les présenter.
Késaco ?
Les symboles sont les objets les plus basiques en Ruby : un nom
associé à un identifiant interne. À chaque fois que vous assignez
le nom d'un symbole à un objet (une variable par exemple) c'est
toujours le même symbole qui est utilisé, donc par conséquent, le
même objet tout au long du programme.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
nom1 = "Karl"
-
nom2 = "Karl"
-
nomA = :Karl # le nom du symbole est Karl
-
nomB = :Karl
Ici, on a assigné la même valeur aux variables nom1 et nom2, puis
on fait de même avec les variables nomA et nomB, à la
différence qu'on leur associe un symbole et non une chaîne de
caractères.
Si on teste l'égalité de ces deux paires de variables, voici ce
qu'on obtient :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
if nom1 == nom2
-
puts "nom1 = nom2"
-
end
-
if nomA == nomB
-
puts "nomA = nomB"
-
end
Code : Console - Afficher / masquer les numéros de
ligne
Les valeurs de ces objets sont identiques deux à deux. Mais lorsque
l'on regarde les objets eux-mêmes :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
if nom1.object_id == nom2.object_id
-
puts "nom1 = nom2"
-
end
-
if nomA.object_id == nomB.object_id
-
puts "nomA = nomB"
-
end
la méthode object_id permet d'accéder
à l'identifiant interne de l'objet.
Code : Console - Afficher / masquer les numéros de
ligne
On peut donc en déduire que nom1 et
nom2 possèdent la même information
mais sont deux objets distincts, alors que nomA et nomB sont
les mêmes objets (ils ont le même identifiant) : car ils sont
associés à un seul et même objet de type Symbol.
Lorsque l'on a déclaré nomA et
nomB, un seul objet Symbol a été créé, cela fait faire une économie
au niveau de la mémoire et du temps d'exécution. Nous venons de
voir que deux objets contenant la référence au même symbole sont
identiques, alors que deux objets contenant la même chaîne de
caractères sont différents. En effet :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
puts :Karl.object_id
-
puts nomA.object_id
-
puts nomB.object_id
-
puts nom1.object_id
-
puts nom2.object_id
Code : Console - Afficher / masquer les numéros de
ligne
190778
190778
190778
21329010
21329000
Convertir chaînes et symboles
Pour transformer un symbole en chaîne de caractères, vous disposez
des méthodes to_s et id2name (identiques ) définies pour les objets Symbol (Symbol#id2name) :
Code : Ruby
puts
nomA.id2name
puts nomB.to_s
Code : Console
Karl
Karl
Pour effectuer l'opération inverse : c'est à dire obtenir le
symbole correspondant à une chaîne de caractères, nous utilisons la
méthode intern de la classe
String (String#intern). Vous pouvez par exemple avoir
l'identifiant interne du symbole associé à la chaîne de caractères
:
Code : Ruby
nom = "Karl"
puts nom
puts nom.intern.object_id
Quand les utiliser ?
Quand est-ce conseillé d'utiliser un
symbole plutôt qu'une chaîne de caractères ?
Si ce que contient l'objet est important, utilisez une chaîne de
caractères :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
nomComplet = "Henri Jean Claude
Philippe" # plus efficace que
-
nomComplet = :HenriJeanClaudePhilippe
Si l'identité de l'objet vous importe, utilisez plutôt un symbole
:
Code : Ruby - Afficher / masquer les numéros de
ligne
-
rang = :admin
# plus efficace que
-
rang = "admin"
Voici un programme d'exemple pour les mettre en pratique, celui-ci
remplacera le QCM.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Ecolier
-
def initialize lang
-
@lang = lang
-
end
-
-
def lang
-
@lang.to_s
-
end
-
end
-
-
Jean = Ecolier.new
:fr
-
Peter = Ecolier.new
:en
-
Karl = Ecolier.new
:de
-
-
puts Jean.lang, Peter.lang,
Karl.lang
Nous avons une classe Ecolier, la
langue de l'écolier est stockée dans la variable @lang. Vous avez sans doute remarqué que la
langue de l'écolier (passée en paramètre lors de l'instanciation)
est sous forme de symbole.
Prenons l'exemple de Jean, sa langue
est associée au symbole :fr. Nous
aurions aussi pu utiliser une chaîne de caractères pour représenter
la langue, mais qu'aurions-nous mis ? "fr" ? "Fr" ? "français" ?
"Français" ?
Dans ce cas, ce que contient la chaîne de caractères ne nous
intéresse pas, seul le fait que Jean parle Français est important.
Nous choisissons donc un symbole.
Il est de ce fait inutile de recréer une nouvelle chaîne de
caractères pour chaque écolier parlant le Français, nous
utiliserons l'unique symbole :fr.
Le plus souvent, les symboles fournissent une alternative aux
chaînes de caractères ; cela ne veut pas dire qu'il faut absolument
que vous les utilisiez. Néanmoins, il faut que vous sachiez qu'ils
existent et que dans certains cas leur utilisation peut vous faire
gagner du temps : à vous de voir si votre situation l'exige.
Ce chapitre n'est qu'une présentation
des symboles. Il en existe d'autres usages, qui seront abordés dans
les chapitres à venir.
Voilà, faites-en bon usage !
Les méthodes (2/2)
Ce qui suit est la suite du chapitre sur les méthodes de la
première partie. Il a été différé car vous aviez besoin des
symboles (abordés au chapitre précédent) avant de le lire ; il est
maintenant temps d'en finir avec ce qu'il vous reste à savoir sur
les méthodes.
Les alias de méthodes
Créer un alias d'une méthode vous
permet de créer une copie conforme de cette méthode, vous obtenez
une nouvelle méthode fonctionnant de manière strictement identique
à la première, disponible sous un nouveau nom. L'intérêt est de
disposer de plusieurs noms pour une seule méthode, ou encore de
conserver l'ancienne méthode (afin de pouvoir éventuellement la
rappeler) avant de la redéfinir.
Cette opération se fait le plus simplement du monde à l'aide du
mot-clé alias suivi du nom de la
méthode à créer et du nom de la méthode originelle, comme
l'illustre cet exemple :
Code : Ruby
def
nomme(nom)
puts nom
end
alias denomme nomme
Nous venons de créer un alias denomme
pour la méthode nomme. Au lieu de
passer les noms des méthodes en question, nous pouvons tout aussi
bien passer les symboles s'y rapportant :
Code : Ruby
alias :denomme
:nomme
Le résultat est le même si vous appelez ces deux méthodes :
Code : Ruby
nomme "Jean"
denomme "Jeanne"
Redéfinir une de ces deux méthodes n'altérera pas l'autre.
alias doit
être suivi de deux méthodes, ni plus, ni moins (la méthode alias en
premier, la méthode à copier en second) !
Paramètres de méthodes
Lors de la déclaration d'une méthode, vous pouvez préciser si
certains paramètres sont optionnels, il est alors possible de leur
assigner une valeur par défaut si vous le désirez. Mais il est
également possible d'envoyer des paramètres supplémentaires à une
méthode, ils seront alors rangés dans un tableau. Voyons comment
procéder :
Code : Ruby
def
hurle(intonation, langue="fr", *duree)
#
end
A travers cet exemple, nous voyons que le paramètre intonation est obligatoire, que le paramètre
langue ne l'est pas : si aucune
valeur n'est précisée sa valeur par défaut sera "fr". La méthode rangera tous les arguments
supplémentaires qu'elle recevra dans un tableau nommé duree.
Ainsi, voici quelques possibilités pour appeler cette méthode :
Code : Ruby
hurle("fort")
hurle("lala",
"en")
hurle("tres
fort", "jap", 5, 6, 9, 27)
Dans le dernier exemple, le tableau duree sera tel que : duree
= [5, 6, 9, 27].
Pour que notre méthode puisse recevoir un nombre quelconque de
paramètres, il nous suffit de la déclarer ainsi :
Code : Ruby
def
hurle(*params)
#
end
Tous les arguments seront placés dans le tableau params.
Appel de méthode de superclasse
Considérons deux classes Machine et
Ordinateur (sous-classe de
Machine) disposant toutes deux d'une
méthode run :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Machine
-
def run
-
puts "une
machine"
-
end
-
end
-
-
class Ordinateur <
Machine
-
def run
-
print "je suis un
ordinateur donc "
-
super
-
end
-
end
Le mot-clé super, placé au sein d'une
méthode, nous permet d'appeler la méthode du
même nom dans la super-classe. Ici, super appelle la méthode run de la classe Machine et nous obtenons :
Code : Console - Afficher / masquer les numéros de
ligne
je suis un ordinateur donc une machine
super peut être placé n'importe où
dans la déclaration de votre méthode, et autant de fois que vous
voulez.
Il appelle la méthode de la super-classe avec exactement les mêmes
paramètres que la méthode dans laquelle il se trouve : dans notre
exemple, il n'y en a aucun. Pour un nombre quelconque de
paramètres, on peut utiliser :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
def run(*params)
-
print "je suis un ordinateur donc
"
-
super
-
end
Tous les paramètres reçus seront envoyés à la méthode de la
super-classe. Nous pouvons aussi choisir de n'en passer que
quelques-uns :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
def run(prix, poids)
-
print "je suis un ordinateur donc
"
-
super(poids)
-
end
Si au contraire, vous ne voulez en passer aucun, l'appel à
super doit être suivi d'une paire de
parenthèses vides :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
def run(*params)
-
print "je suis un ordinateur donc
"
-
super()
-
end
Ici, aucun des paramètres stockés dans params ne sera envoyé à la méthode appelée par
super.
Les accesseurs
Les accesseurs sont des méthodes particulières qui vous permettent
d'accéder aux variables d'instance de votre objet pour les lire ou
les modifier. Vous pouvez bien entendu les écrire vous-mêmes, par
exemple pour une classe Ordinateur
ayant une variable d'instance @prix
:
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Ordinateur
-
def prix=(arg); @prix = arg; end
-
def prix; @prix; end
-
end
-
-
monOrdi = Ordinateur.new
Il nous suffit d'appeler la méthode prix= sur l'objet monOrdi afin de modifier la variable @prix, et un appel à prix retourne la valeur de cette variable
d'instance :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
monOrdi.prix =
400
-
puts monOrdi.prix
La première méthode est une méthode d'écriture (ou setter) puisqu'on modifie la variable, tandis que
la seconde est une méthode de lecture (ou getter) puisqu'on ne s'intéresse qu'à la valeur
actuelle de la variable en question.
Il peut être long (et fastidieux) de définir ces méthodes pour
chacune de nos variables d'instance : aussi Ruby peut s'en charger
à notre place et c'est ce que nous allons voir maintenant.
attr_reader
En déclarant :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Ordinateur
-
attr_reader
:prix
-
end
nous passons le symbole :prix à la
méthode attr_reader (Module#attr_reader) : cela a pour effet de créer
la méthode de lecture pour cette variable. Nous pouvons donc
utiliser monOrdi.prix comme si nous
l'avions défini nous-mêmes.
Pour définir plusieurs de ces méthodes en une seule fois, il suffit
de passer tous les symboles (correspondants aux variables
d'instance) à la méthode attr_reader
:
Code : Ruby - Afficher / masquer les numéros de
ligne
-
attr_reader :prix,
:puissance, :poids
attr_writer
Pour disposer de la méthode d'écriture, le principe est le même :
Ruby met à notre disposition une méthode attr_writer à laquelle nous passons les symboles
correspondant aux variables d'instance :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Ordinateur
-
attr_writer
:prix
-
end
Ceci nous permet d'utiliser monOrdi.prix= comme si nous l'avions défini
nous-mêmes.
attr_accessor
Une dernière méthode, attr_accessor
(Module#attr_accessor), fonctionnant
de la même manière que les deux précédentes, permet de déclarer en
une seule fois les méthodes de lecture et d'écriture pour chaque
variable passée en paramètre.
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class Ordinateur
-
attr_accessor
:prix
-
end
Nous pouvons donc écrire :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
monOrdi.prix =
400
-
puts monOrdi.prix
Les prochains chapitres aborderont divers aspects du langage comme
les bases de données, les fichiers, etc.
Comme promis, la prochaine partie du tutoriel sera consacrée à Ruby
on Rails, je vous y attends.
Cette partie n'est pas terminée.
Partie 3 : Ruby sur le Net : Ruby on Rails
Mais Ruby c'est aussi Ruby on Rails : un
framework, c'est à dire un ensemble
de bibliothèques et de conventions permettant le développement
rapide d'applications. C'est un outil de développement très
productif qui s'appuie sur le langage Ruby (j'espère que vous vous
êtes intéressés à la première partie ).
Il permet de développer des applications web
riches (et donc des pages dynamiques) en Ruby et peut être
associé aux technologies AJAX (JavaScript + XML) et même PHP. Vous
apprendrez à tirer profit de ces possibilités dans cette troisième
partie.
Histoire de vous faire saliver, voici un annuaire recensant des
applications web créées avec Rails : BusinessOnRails.com
Rails ? Késaco ?
Ce premier chapitre servira essentiellement à vous présenter cet
outil qu'est Rails. Parce que vous avez besoin d'apprendre à le
connaître avant d'apprendre à vous en servir.
Tout d'abord qu'est-ce que l'architecture
Modèle-Vue-Contrôleur ? Ceux qui ont déjà une bonne
expérience de la programmation connaissent peut-être déjà la
réponse. Quoi qu'il en soit, nous y répondrons pour ne pas rester
dans le vague !
Puis suivra l'étape essentielle, cruciale, de l'installation de
Rails sur votre machine, très rapide en soi; et enfin, viendra le
moment de la prise en main tant attendue.
Modèle - Vue - Contrôleur
Le développement avec Rails est organisé suivant le concept de
Modèle-Vue-Contrôleur (abrégé MVC), il est ce
qu'on appelle un motif de conception (le thème que vous risquez de
rencontrer le plus souvent est Design Pattern).
Les Patterns sont des techniques mises en oeuvre afin de simplifier
la conception logicielle ou faciliter la résolution de problèmes
spécifiques à la programmation.
Dans ce cas, le motif MVC a pour but de séparer le code de
l'application en 3 parties distinctes :
- le Modèle : pour la gestion des données, l'interaction avec la
Base de Données se fait par des classes Ruby qui masquent le
dialogue avec la base (donc, pas une seule ligne de SQL).
- la Vue (interface utilisateur) : ce sont les pages web telles
qu'elles seront visibles, le plus souvent ce sont des fichiers
.rhtml (des
pages HTML avec du code Ruby), mais vous pouvez aussi produire des
fichiers .rxml (du XML couplé à du Ruby). La Vue se
base sur les données du Modèle.
- le Contrôleur : ce sont des classes Ruby qui coordonnent les
interactions entre les Modèles et les Vues.
De cette manière, la maintenance est d'autant plus simple qu'un
designer n'est pas obligé de mettre le nez dans du code Ruby et
qu'un développeur n'a pas à s'occuper du code HTML.
Pour résumer brièvement :
Citation : Article MVC de Wikipédia
Lorsqu'un client envoie une requête à
l'application, celle-ci est analysée par le
Contrôleur, qui demande au Modèle
approprié d'effectuer les traitements, puis renvoie la
Vue adaptée au navigateur, si le modèle ne l'a pas
déjà fait.
Installation de Rails
Vous savez maintenant comment est architecturée une application
Rails, mais il serait temps de penser à l'acquérir. Pour ce faire
vous devez déjà posséder une version de Ruby sur votre ordinateur,
si ce n'est pas le cas, rendez-vous
ici pour choisir la version correspondant à votre système
d'exploitation. Précisons au passage que Rails, tout comme Ruby,
fonctionne sur plusieurs plate-formes (Windows, GNU/Linux, Mac OS
X, etc.).
Vous devez également posséder une version de la bibliothèque
Rubygems, si vous êtes sous Windows elle se trouve
déjà dans le pack que vous avez téléchargé, sinon il faudra vous
rendre ici
afin de la télécharger (la dernière version stable de préférence),
décompressez ensuite l'archive dans le répertoire où vous avez
installé Ruby, et installez le de cette manière :
Code : Console - Afficher / masquer les numéros de
ligne
L'installation devrait avoir lieu sans encombre, tapez en console
:
Code : Console - Afficher / masquer les numéros de
ligne
Quelques questions vous seront posées
pendant l'opération, ne vous en souciez pas, répondez toujours par
l'affirmative en tapant Y.
C'est tout, la vitesse de l'installation peut varier suivant la
puissance de votre connexion, mais c'est tout.
Cette commande s'est chargée d'installer sur votre ordinateur tous
les fichiers que contient la gemme Rails, à savoir quelques
bibliothèques et le programme en ligne de commande Rails qui vous
permettra de lancer vos applications.
Lorsque le téléchargement est terminé ou que vous disposiez déjà de
Rails, la console vous affiche cet heureux message :
Code : Console - Afficher / masquer les numéros de
ligne
Successfully installed rails-1.1.6
Rails est désormais opérationnel, vous pouvez passer à l'étape
suivante.
Premiers pas
Vous avez sûrement envie d'essayer RoR, tout fraîchement installé,
non ? C'est pourquoi je vous propose de faire dès lors une petite
visite guidée de l'outil. Mais ne brûlons pas les étapes, Rails est
un sujet assez vaste pour vous tenir en haleine sur plusieurs
chapitres.
Pour éditer vos fichiers, vous pouvez vous servir de n'importe quel
IDE, mais il en existe un particulièrement efficace pour le
développement d'applications Rails : RadRails. Il est
développé en Java et possède tous les avantage d'Eclipse :
coloration syntaxique du code, débogage, onglets, arborescence de
l'application à portée de clic, création de projet simplifiée,
aperçu dans le navigateur, etc.
Création de projet
Tout d'abord, gardez en tête que votre application sera créée dans
le répertoire sur lequel pointe la console : le même que celui qui
doit contenir vos programmes Ruby afin de les lancer en ligne de
commande. Dans cet exemple, nous considérons que ce répertoire est
tout simplement C:\.
Exécutez la commande rails suivie du
nom de votre application :
Code : Console - Afficher / masquer les numéros de
ligne
Dans ce cas, votre application se trouve ici : C:\tutoRuby.
Mais vous pouvez également préciser son emplacement au sein du
répertoire :
Code : Console - Afficher / masquer les numéros de
ligne
Ici, votre application se trouve dans le répertoire : C:\sdz\tutos\tutoRuby.
Comme vous avez pu le constater, suite à la simple exécution de la
commande rails, RoR a généré
automatiquement tous les fichiers "de base" nécessaires à votre
application, fichiers dont vous pouvez voir la liste affichée en
console. Nous nous y attarderons plus tard. Pour le moment, lançons
l'application. Pour cela, vous devez changer le répertoire-cible de
la console, celle-ci doit pointer sur votre application. Nous allons réutiliser la
commande cd, vue précédemment :
Code : Console - Afficher / masquer les numéros de
ligne
Pour lancer l'application rails, lancez la commande :
Code : Console - Afficher / masquer les numéros de
ligne
Rails vous informe par l'intermédiaire de la console que le serveur
WEBrick (serveur web intégré à Ruby sur lequel
repose Rails, c'est l'équivalent de ce qu'Apache est à PHP par
exemple ) a été
démarré et que votre application est visible à cette adresse :
http://127.0.0.1:3000/. Vous
pouvez lancer votre navigateur afin de le constater par
vous-mêmes.
Création de fichiers MVC
Générer des Modèles
Comme dit précédemment, les Modèles sont en fait
des classes Ruby : ce sont des sous-classes de ActiveRecord::Base. ActiveRecord est une
bibliothèque masquant l'interaction entre la Base de Données et
l'application ; son utilisation est entièrement basée sur des
conventions de nommage que nous étudierons plus tard. Chaque sous-classe de
ActiveRecord::Base correspond à une
table de la Base de Données de votre application. Pour créer une
base nommée chapitres, voici
l'instruction :
Code : Console - Afficher / masquer les numéros de
ligne
ruby script/generate model chapitre
Vous pouvez voir qu'un fichier Ruby a été créé à l'emplacement
C:\tutoRuby\app\models\chapitre.rb,
il ne contient que la définition de la classe Chapitre.
L'utilisation de ce Modèle sera abordée ultérieurement.
Générer des Vues et des Contrôleurs
Pour créer un Contrôleur, la manipulation est
quasiment la même que pour les Modèles. Ainsi pour créer un
Contrôleur nommé chapitre :
Code : Console - Afficher / masquer les numéros de
ligne
ruby script/generate controller chapitre
Il est également possible de générer des méthodes pour le
contrôleur : supposons que nous voulions définir les méthodes
add et delete, l'instruction à entrer en console serait
alors :
Code : Console - Afficher / masquer les numéros de
ligne
ruby script/generate controller chapitre add delete
Le fichier Ruby correspondant est désormais situé ici :
C:\tutoRuby\app\controllers\chapitre_controller.rb
et il contient le code de la classe ChapitreController (sous-classe de ApplicationController), ainsi que la définition
de nos deux méthodes add et
delete.
En général, il y a une Vue (un fichier
.rhtml)
pour chaque méthode du Contrôleur : en effet, lors de la création
du Contrôleur, des Vues ont été créées automatiquement :
C:\tutoRuby\app\views\chapitre\add.rhtml et
C:\tutoRuby\app\views\chapitre\delete.rhtml.
Bien entendu, vous n'obtiendrez rien d'utile en laissant tous ces
fichiers MVC tels qu'ils le sont actuellement.
Le but de ce chapitre était de vous montrer la facilité
d'utilisation de Rails (facilité déconcertante
). Notre exploration
continue, prochaine étape à travers un exemple concret : les Bases
de Données.
Les bases de données
Vous savez que les applications Rails sont bâties sur le motif
Modèle-Vue-Contrôleur, ce qui vous permet de mettre un peu d'ordre
dans votre code ainsi que dans vos données. Mais encore faut-il
pouvoir les stocker ces données.
Ce chapitre aborde la gestion des bases de
données, voyez qu'elle s'appuie avant tout sur des
conventions de nommage qui sont respectées par les
développeurs Rails, par le framework, et donc que vous devez vous aussi respecter.
Créer une base et une table
Tout d'abord, créons le projet, nommé par exemple blog et plaçons-nous à l'intérieur de ce
répertoire.
Code : Console
rails blog
cd blog
Occupons-nous ensuite de créer la base de données : utilisez le
logiciel d'administration de base de données que vous voulez,
plusieurs sont disponibles (citons entre autres MySQL-Front et
HeidiSQL pour MySQL) et une simple recherche sur un moteur de
recherche suffit pour en trouver.
Dans le fichier config/database.yml
vous pouvez voir l'ensemble des bases de données utilisées par
l'application, la seule qui nous importe pour l'instant est la
première que voici :
Code : Ruby
development:
adapter: mysql
database: blog_development
username: root
password:
host: localhost
Elle est configurée pour être utilisée en local (en effet, l'hôte
est localhost, l'utilisateur est
root et le mot de passe est vide), si
vous placez votre application sur un hébergeur compatible avec
Rails, assurez-vous de modifier ces quelques paramètres.
Précisons également qu'elle est (par défaut) prévue pour
fonctionner avec le modèle de base de données
MySQL comme en témoigne l'adapter
de la base. MySQL est un des systèmes de base de données les plus
connus, c'est celui que vous apprend à utiliser le cours sur le PHP
du
Site du Zéro, mais il est bien évidemment possible d'en
utiliser d'autres dont voici la liste des adaptateurs :
MySQL |
mysql |
PostgreSQL |
postgresql |
Oracle |
oci |
Microsoft SQL Server |
sqlserver |
SQLite2 |
sqlite2 |
SQLite3 |
sqlite3 |
DB2 |
db2 |
Système BDD |
Adaptateur |
Vous devez donc modifier l'adaptateur pour votre système de base de
données si besoin est, puis renommez cette base : utilisez le nom
de la base créée spécialement pour ce projet au début du chapitre
(blograils pour ma part). Ne vous
préoccupez pas des autres bases pour le moment.
Créons maintenant le modèle correspondant à la table articles qui stockera les différents articles de
notre blog. Le nom du modèle doit être au
singulier.
Code : Console
ruby script/generate model article
Un fichier a été créé dans le dossier /db/migrate/, il présente l'organisation de votre
table articles. Nous allons donc
utiliser les migrations : Rails garde en mémoire
les différentes "versions" de la structure de la table, les deux
méthodes de la classe sont là pour effectuer le passage d'une
version à une autre. Pour modifier la structure de notre table,
intéressons-nous à la méthode self.up
:
Code : Ruby
def self.up
create_table :articles do |t|
# t.column :name,
:string
end
end
Nous souhaitons que la table articles
contienne les champs nom (une chaîne
de 20 caractères maximum), contenu
(du texte), commentaires_count (un
entier) et date (la date d'ajout).
Nous allons donc modifier le contenu de l'itérateur de cette façon
:
Code : Ruby
t.column :nom,
:string, :limit => 20, :null => false
t.column :contenu, :text, :null =>
false
t.column :commentaires_count,
:integer, :default => 0
t.column :date, :datetime
Ça peut vous paraître obscur de prime abord, mais il n'en est rien,
avec quelques bases en Anglais courant, tout s'illumine, vous
pouvez voir que les informations sont contenues dans des symboles
:
:nom, :contenu, etc. |
noms des champs de la table |
:string |
type du champ (chaîne de caractères) |
:text |
type du champ (texte long) |
:integer |
type du champ (entier) |
:datetime |
type du champ (date) |
:null |
indique si le champ peut être laissé vide |
:default |
valeur par défaut |
:limit |
longueur maximale du champ |
symbole |
signification |
Tous ces symboles font partie d'une convention sur laquelle repose
le framework. C'est justement cette convention qui vous évite
d'avoir à écrire du code SQL.
Règle de mise au pluriel
Techniquement, vous pouvez appeler vos modèles comme vous le
souhaitez (les noms donnés ici sont des exemples), mais il existe
une convention de nommage qui régit les noms de modèles et des
tables associées.
Règle de mise au pluriel : un modèle
(une classe) au singulier correspond à une table au pluriel. C'est
ce que nous avons fait ici : nous avons généré un modèle
article et il en résultera une table
articles. Tout ceci est pris en
charge par la classe ActiveRecord et
vous n'avez pas à vous en préoccuper tant que vous respectez cette
règle.
Pour les noms non-anglais (et ceux
non-recensés), la mise au pluriel se résume à l'ajout d'un
s à la fin du mot, donc veillez à ce
que le nom du modèle que vous voulez créer ait un pluriel "en
s" (donc, pas
oeil).
Le nom de la table sera toujours en minuscules. De plus, si vous
créez un modèle nommé de cette façon :
Code : Console - Afficher / masquer les numéros de
ligne
ruby script/generate model blogTest
vous obtiendrez une table nommée blog_tests : une majuscule au milieu d'un mot est
interprétée comme la séparation de deux mots, cette limite est
remplacée par un tiret bas (underscore), le tout est ensuite mis en
minuscules et un s est ajouté à la
fin de la chaîne.
Nous ne nous en servirons pas ici, mais ça peut s'avérer utile.
Les relations entre les tables
Supposons que nous voulions que notre table articles soit mise en relation avec une autre
table dans laquelle seront stockés les différents commentaires du
blog. Pour la créer, il faut générer le modèle associé dont le nom
n'est autre que celui de la table au singulier (souvenez-vous de la
convention) :
Code : Console
ruby script/generate model commentaire
Le modèle est créé, de même que la table associée, nommée
commentaires. Jetez un coup d'oeil au
fichier de migration de cette table, nous voulons qu'elle contienne
les champs suivants : contenu (du
texte), date (la date d'ajout) et
article_id (un entier).
Code : Ruby
t.column :contenu,
:text, :null => false
t.column :article_id, :integer
t.column :date, :datetime
Comme vous l'avez peut-être remarqué, le champ article_id de cette table doit correspondre au
champ id (pris en charge
automatiquement) de la table articles. On retrouve ici une autre convention :
le nom du champ servant de lien doit correspondre au nom singulier
de la table que vous voulez lier (ici : article), suffixé de _id, ce qui est donc le cas.
Cette liaison se prolonge avec le champ :commentaires_count de la table articles : dans notre exemple, il contient
(automatiquement) le nombre de commentaires rattachés à
l'article.
Et pour finir, le champ :date
contient la date d'ajout des données, sans que vous ayez à les
inscrire manuellement.
Nos tables sont prêtes, effectuons la migration :
Code : Console
rake migrate
Les migrations permettent également de
modifier les tables
Le fichier db/schema.rb est généré et
contient la structure de nos deux tables, il ne nous reste plus
qu'à les relier. Deux tables peuvent avoir 4 types de relations
différentes :
- l'appartenance belongs_to
- la parenté unique has_one
- la parenté multiple has_many
- l'appartenance et la parenté multiple has_and_belongs_to_many
Dans notre exemple, un article peut avoir plusieurs commentaires.
Les relations inter-tables seront donc :
- commentaire belongs_to
article
- article has_many
commentaires
Elles seront retranscrites presque telles quelles dans nos modèles
:
Code : Ruby
#app/models/article.rb
class Article < ActiveRecord::Base
has_many :commentaires, :dependent
=> true
end
#app/models/commentaire.rb
class Commentaire <
ActiveRecord::Base
belongs_to :article, :counter_cache
=> true
end
:counter_cache incrémente le compteur
:commentaires_count de la table
articles à chaque ajout et le
décrémente à chaque suppression.
:dependent indique qu'un commentaire
est dépendant d'un article : pas de commentaire sans article.
Ajouter, modifier et supprimer des
données
Pour pouvoir effectuer ces quelques actions sur les données du
blog, nous devons créer un contrôleur pour chacune de ces actions,
ce qui équivaut à taper en console :
Code : Console
ruby script/generate controller article ajout edit supp
ruby script/generate controller commentaire ajout edit supp
Puis à coder nous mêmes ces actions.
Mais comme nous sommes très
fainéants, laissons Rails le faire pour nous ! (après tout, c'est
faisable donc pourquoi s'en passer ? )
Code : Console
ruby script/generate scaffold article
ruby script/generate scaffold commentaire
Ceci est un scaffolding (traduisez
échafaudage) : la commande scaffold
génère les contrôleurs et les vues de cet embryon de méthodes
complémentaires :
- list (liste les données)
- show (affiche les données)
- new (ajoute des données)
- edit (modifie des données)
- destroy (supprime des
données)
Vous devez lui indiquer en paramètre le nom du modèle correspondant
(ici article), puis en paramètres
optionnels le nom du contrôleur (sinon c'est automatiquement le nom
du modèle) et les méthodes que vous souhaitez définir (autant que
vous voulez, leurs vues sont également créées). Voici un autre
exemple plus farfelu : (ne le lancez pas, cela ne fera que
surcharger votre code
)
Code : Console
ruby script/generate scaffold article blog remise_a_zero verrouiller_blog
Et cela conviendra donc à (presque ?) toutes les applications que
vous ferez avec une base de données, à utiliser sans modération
bien entendu.
Un petit coup d'oeil à l'application avant de poursuivre ?
Code : Console
ruby script/server
http://127.0.0.1:3000/articles
http://127.0.0.1:3000/commentaires
Ne nous arrêtons pas en si bon chemin, les tables sont créées, le
système d'ajout, d'édition et de suppression des données est mis en
place, mais il nous reste à approfondir l'affichage de ces données.
C'est ce qui vous attend au chapitre suivant.
Relations Vue-Contrôleur
Vous savez stocker des données dans la base de données d'une
application Rails. Il est maintenant fondamental de comprendre
comment les afficher. Même si vous n'avez pas recours à une base de
données (car oui, ce n'est pas systématique) vous aurez sans doute
besoin d'afficher des données. Cet affichage se fait par
l'intermédiaire de ce qu'on nomme les gabarits (ou modèles)
ERb et que nous allons étudier dès maintenant.
Les modèles ERb
Le gabarit ERb est le composant essentiel des
fichiers .rhtml. Pour simplifier, c'est du code Ruby
qui est interprété au sein d'une Vue, de manière similaire au PHP
et aux JavaServerPages (JSP). Ce même code est situé entre deux
balises, elles-mêmes semblables à celles du PHP ou des JSP :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
<% message = 'Bienvenue
!' %>
Le code Ruby entre ces deux balises sera exécuté mais ne sera pas
affiché, nous pouvons donc y placer des boucles ainsi que des
déclarations et des assignations de variables. Pour afficher le
code exécuté, il nous faut modifier la balise ouvrante :
Code : Ruby - Afficher / masquer les numéros de
ligne
Les modèles ERb génèrent les Vues de l'application dans les
fichiers .rhtml : vous ne devrez donc jamais utiliser
des méthodes de sortie standard telles que puts ou print au
sein des modèles !
Une autre remarque importante : ne
placez pas de balises <html></html> ou <body></body> dans un modèle ERb, la
page est automatiquement générée au format HTML, comme vous pouvez
le voir dans le dossier app/views/layouts.
Récupérer les données du Contrôleur
Les Vues n'exécutent et n'affichent pas seulement les instructions
contenues au sein des modèles ERb, vous pouvez également leur
passer des données depuis le Contrôleur.
Prenons l'exemple d'une vue test.rhtml correspondant à une action
test du contrôleur associé. Voyons
comment une variable originellement dans un contrôleur peut être
affichée dans une vue. Voici le contenu du contrôleur articles_controller.rb :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class ArticlesController
< ApplicationController
-
def test
-
@test =
'Ceci est un test'
-
$glob1 =
'Globale interne'
-
end
-
$glob2 =
'Globale externe'
-
end
Et la vue test.rhtml :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
<p><%= @test
%></p>
-
<p><%= $glob1
%></p>
-
<p><%= $glob2
%></p>
Utiliser une variable d'instance est la méthode la plus courante
pour transmettre des données entre le contrôleur et la vue. Mais
dans certains cas, vous serez amenés à utiliser des variables
globales, qui comme vous pouvez le voir peuvent être aussi bien
déclarées à l'intérieur qu'à l'extérieur d'une méthode.
Convertir les caractères spéciaux en leur entité HTML
Pour éviter que du code HTML ne s'invite dans vos vues (ce qui peut
par exemple interférer avec la mise en page originelle du site, ou
exécuter du code JavaScript), Rails met à votre disposition une
méthode, h(), qui convertit les
caractères spéciaux en leur équivalent HTML. Reprenons notre
exemple, le contrôleur articles_controller.rb :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
class ArticlesController
< ApplicationController
-
def test
-
@test =
'<em>Ceci est un
test</em>'
-
end
-
end
La vue test.rhtml :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
<p>HTML interprété : <%= @test %></p>
-
<p>HTML converti, non-interprété : <%= h
@test %></p>
Sélectionner des enregistrements dans une
base de données
Avant de pouvoir afficher des données stockées dans une base de
données, vous devez utiliser une requête pour les sélectionner.
Généralement, le résultat d'une telle sélection est placée dans une
variable d'instance. En considérant l'exemple d'un Modèle nommé
Article, si nous voulons sélectionner
tous les enregistrements dans la base de données, il nous faut
procéder ainsi :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
@articles =
Article.find(:all)
:all indique clairement que tous les
enregistrements sont concernés. Mais il ne nous empêche pas de
restreindre notre sélection. En effet, la méthode find nous permet de trier ces données selon
différents critères.
Pour une sélection numérique, il nous faut renseigner le symbole
:limit :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
@articles =
Article.find(:all, :limit => 10)
Ainsi, nous obtenons les 10 premiers articles de toute la base de
données.
Pour modifier le critère du classement, indiquez le champ de la
table à prendre en compte avec le symbole :order :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
@articles =
Article.find(:all, :order => 'date')
De cette manière, les articles sont affichés suivant leur date.
Il est également possible de préciser d'autres conditions, telles
que des contrôles de valeur (des égalités, par exemple). Cette
condition facultative doit être renseignée via le symbole
:conditions :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
@articles =
Article.find(:all, :conditions => 'date IS
NULL')
-
@articles =
Article.find(:all, :conditions => 'date IS NOT
NULL')
-
@articles =
Article.find(:all, :conditions => 'commentaires_count' == 0)
Vous pouvez bien entendu affiner la sélection en combinant les
différents critères cités ci-dessus.
Les liens
Les liens les plus courants se présentent de cette manière :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
<%= link_to 'Accueil du
site', :action => 'index' %>
La méthode link_to s'occupe de
générer le lien pour vous, elle prend en argument le nom du lien et
sa cible. En premier lieu est donc indiqué le texte du lien :
Accueil du site. :action désigne la vue vers laquelle nous nous
dirigeons : dans cet exemple, le lien pointe en direction de
index.rhtml.
Il est également possible de passer un paramètre à l'URL ; voici
comment elle se décompose alors :
http://127.0.0.1:3000/contrôleur/action/paramètre
par exemple :
http://127.0.0.1:3000/articles/show/4
Pour passer un tel paramètre, vous devez modifier le lien de cette
manière :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
<%= link_to 'Accueil',
:action => 'index', :id =>
4 %>
Et pour le récupérer dans le contrôleur correspondant à l'action,
rien de plus simple :
Code : Ruby - Afficher / masquer les numéros de
ligne
-
@article =
Article.find(:all, :limit => params[:id])
Cet exemple vous permet de passer en argument l'id de l'article que vous voulez sélectionner,
mais il y a de nombreuses manières d'en tirer profit.
Afficher des données avec Rails est aussi simple que ça. La
prochaine étape de notre apprentissage sera celle des sessions et
des cookies, que Rails nous permet de manipuler aussi simplement
que tout le reste.
Cette partie n'est pas terminée.
Partie 4 : Annexes
Dans les Annexes vous trouverez des chapitres additionnels, liés à
certains aspects du cours, dont la lecture n'est pas obligatoire ;
à lire quand vous voulez et pas nécessairement à la fin.
Mots réservés
Les mots réservés (ou mots-clés) sont des éléments du langage, ils
font partie de Ruby. Vous ne devez pas utiliser leur nom pour
définir une variable, une classe, une méthode, etc.
Liste des mots réservés
Pour une référence rapide :
- =begin
- =end
- BEGIN
- END
- alias
- and
- begin
- break
- case
- class
- def
- defined?
- do
- else
- elsif
- end
- ensure
- false
- for
- if
- in
- module
- next
- nil
- not
- or
- redo
- rescue
- retry
- return
- self
- super
- then
- true
- undef
- unless
- until
- when
- while
- yield
- __FILE__
- __LINE__
Détails des mots réservés
Pour une description plus complète :
=begin |
débute un bloc de commentaires |
=end |
clôt un bloc de commentaires |
BEGIN |
débute un bloc de code exécuté pendant le chargement du
programme, s'il y en a plusieurs, ils sont exécutés dans l'ordre où
ils sont énoncés
Code : Ruby
BEGIN
{
}
|
END |
débute un bloc de code exécuté à la fin du programme, s'il y en
a plusieurs, ils sont exécutés dans l'ordre inverse de leur
énonciation
Code : Ruby
END
{
}
|
alias |
crée un alias de méthode
Code : Ruby
def
nomme(nom);
puts nom; end
alias :denomme :nomme #
le nom de l'alias avant celui de la méthode originelle
|
and |
combine deux conditions : et,
équivalent à && |
begin |
débute une boucle (conditionnelle) dont la condition est placée
à la fin; elle est parcourue au moins une fois
Code : Ruby
begin
#
end while()
|
break |
interrompt une boucle
Code : Ruby
while()
break
if()
end
|
case |
début de boucle conditionnelle |
class |
débute la déclaration d'une classe
Code : Ruby
class Machine;
end
|
def |
débute la déclaration d'une méthode
Code : Ruby
def maMethode;
end
|
defined? |
vérifie l'existence d'une variable
Code : Ruby
defined?
maVariable
|
do |
peut remplacer l'accolade ouvrante {
Code : Ruby
loop do # boucle loop
#
end
(0..5).each do |n| # itérateurs each et dérivés
#
end
|
else |
choix alternatif et final dans une condition |
elsif |
choix alternatif dans une condition |
end |
fin d'un bloc d'instructions, peut remplacer une accolade
fermante } |
ensure |
débute un bloc d'instructions toujours exécutées, même si des
exceptions sont soulevées et non gérées
Code : Ruby
begin
#
ensure
#
end
si l'on place le mot-clé rescue pour
la gestion des exceptions, celui-ci doit précéder ensure
Code : Ruby
begin
#
rescue
#
ensure
#
end
|
false |
valeur booléenne : faux |
for |
début de boucle conditionnelle |
if |
début de condition |
in |
précise un ensemble d'éléments (dans un tableau ou un ensemble
de nombres) |
module |
débute la déclaration d'un module |
next |
recommence une boucle avec la valeur suivante
Code : Ruby
# puts n'est pas exécuté
si n<3, on passe à n+1
n=0
while n<5
n += 1
next if n
< 3
puts n
end
|
nil |
valeur vide = rien |
not |
négation, équivalent à ! |
or |
combine deux conditions : ou,
équivalent à || |
redo |
réexécute une boucle sans réévaluer la condition
Code : Ruby
# cette boucle va jusqu'à
15 et non 5
n=0
while n<5
puts n
n +=1
redo if n
<= 15
end
|
rescue |
débute un bloc de gestion des exceptions
Code : Ruby
begin
#
rescue
# gestion des exceptions
end
|
retry |
réinitialise une boucle
Code : Ruby
# attention, ceci est une
boucle infinie !
for n in
(1..5)
puts n
retry if n
== 4
end
|
return |
retourne une valeur |
self |
se réfère à l'objet qui appelle la méthode
Code : Ruby
class Bavard
def
initialize; puts self.blabla; end
def blabla;
return "blabla";
end
end
|
super |
appelle la méthode de la super-classe
Code : Ruby
class Machine
def run
puts "une
machine"
end
end
class Ordinateur < Machine
def run
print "je suis un
ordinateur donc "
super
end
end
|
then |
mot-clé optionnel se plaçant après une condition afin d'en
faciliter la lecture
Code : Ruby
if(x < y)
then puts
"..."
end
|
true |
valeur booléenne : vrai(e) |
undef |
annule la définition d'une méthode
Code : Ruby
def maMethode;
end
undef maMethode
maMethode # erreur : méthode non
définie
|
unless |
début de condition, contraire de if |
until |
début de boucle conditionnelle, contraire de while |
when |
début de cas conditionnel d'une boucle case |
while |
début de boucle conditionnelle |
yield |
désigne le bloc de code passé à une méthode
Code : Ruby
def nomme;
puts yield;
end
nomme { "jean"
}
# mais aussi
def nomme; yield;
end
nomme { puts
"jean" }
|
__FILE__ |
valeur du fichier courant |
__LINE__ |
valeur de la ligne courante |
Mot-clé |
Description |
Utiliser un de ces mots pour définir ce pour quoi il n'a pas été
créé est potentiellement une source d'erreur. Le mieux est de tous
les connaître (de nom uniquement). Mais si vous utilisez un éditeur
de texte proposant une coloration syntaxique adaptée au Ruby, vous
pourrez voir que ces mots sont colorés différemment des autres
caractères.
[Rails] Liste des hébergeurs
Bon, vous avez créé une sympathique application Rails, mais
pourquoi être le seul à en profiter ?
Vous souhaitez donc la rendre accessible au plus grand nombre, il
vous faut pour cela un hébergeur. Or, même si cela est de moins en
moins vrai (et tant mieux ) les hébergeurs qui vous permettent de faire tourner
une application Rails sur leurs serveurs sont plutôt rares.
Je vous ai donc préparé une liste et un comparatif de plusieurs de
ces hébergeurs, dans le but de vous faire gagner du temps (liste
non exhaustive, vous pouvez me signaler d'autres hébergeurs). Il y
a de tout, du gratuit, du payant, du généreux, du moins bon. Les
informations présentées ci-dessous sont celles indiquées sur les
sites des hébergeurs, je décline tout responsabilité si elles se
révèlent fausses, mais signalez-le moi pour que je rectifie.
Pour les prix indiqués en $ (USD : Dollars américains), vous avez
le droit d'utiliser le convertisseur du TP de la première partie
pour avoir l'équivalent en Euros.
Hébergeurs gratuits
Hébergeur |
Espace disque |
Bande passante (par mois) |
Langages |
Bases de données |
Commentaires |
FreeOnRails |
100 Mo |
1 Go |
Rails 1.0.0 + PHP 5 + Perl |
MySQL 4.1 |
Vous devez avoir votre propre nom de domaine |
AmbitiousLemon |
illimité |
illimitée |
Rails 1.2 + PHP 5.2 + Perl 5.2 |
MySQL 5 + PostgreSQL 8 |
Vous devez avoir votre propre nom de domaine et mettre en ligne une version anglaise de votre
site. Offre réservée aux étudiants, artistes et développeurs
de logiciels libres |
Hébergeurs payants
Hébergeur |
Espace disque |
Bande passante (par mois) |
Langages |
Bases de données |
Prix (par mois) |
Commentaires |
Hosting Rails |
de 5 à 75 Go |
de 20 à 150 Go |
Ruby 1.8 + Rails 1.2 + PHP 5 + Perl 5 + Python 2 (django) |
MySQL 5 + PostgreSQL 8 + SQLite 3 |
à partir de $3.59 |
- |
BlueHost.Com |
300 Go |
3 To |
Rails + PHP 4 ou 5 + Perl 5 + Python |
MySQL 5 + PostgreSQL |
$6.95 |
Nom de domaine inclus avec l'offre de 12 ou 24 mois |
STRATO |
de 200 Mo à 20 Go |
de 30 Go à illimité |
PHP 3, 4, 5 + Perl + Ruby + Python |
MySQL |
à partir de 1.06 Euros |
Nom de domaine inclus. Satisfait ou remboursé |
Typhon |
1 Go |
10 Go |
Ruby 1.8.4 + Rails 1.1.2 |
1 base MySQL + 1 base PostgreSQL |
24 Euros/3mois |
Offre de découverte, d'autres offres sont
disponibles. Domaine hébergeable ou sous-domaine .typhon.org |
DreamHost |
de 146 à 366 Go |
de 1.46 à 3.66 To |
PHP 4, 5 + Rails |
MySQL |
à partir de $7.95 |
Nom de domaine inclus |
HostMySite.com |
20 Go |
500 Go |
PHP 4, 5 + Rails + Perl + Python + ASP |
MySQL 5 |
à partir de $8.95 |
Nom de domaine inclus |
Site5 |
de 10 à 30 Go |
de 20 Go à 1.5 To |
Rails |
MySQL |
à partir de $6.97 |
- |
RailsPlayground.com |
de 3 à 30 Go |
de 30 à 800 Go |
PHP 4, 5 + Perl 5 + Rails + Python |
MySQL 5 + PostgreSQL 8 + SQLite |
à partir de $5 |
Nom de domaine non inclus |
A2 Web
Hosting |
de 200 Mo à 20 Go |
de 2 à 200 Go |
PHP 5 + Rails 1.2 + Perl + Python |
MySQL 4 ou 5 + PostgreSQL 8 |
à partir de $2.95 |
Nom de domaine non inclus |
MonkeyWrench
Hosting |
de 100 Mo à 5 Go |
de 10 à 140 Go |
PHP 5 + Rails + Python |
MySQL |
à partir de $2.50 |
- |
A Small
Orange |
de 75 Mo à 4.5 Go |
de 3 à 100 Go |
PHP 4, 5 + Rails 1.2 + Python 2.4 + Perl 5.8 |
MySQL 5 |
à partir de $25/an |
Nom de domaine non inclus. 30 jours de garantie |
BlueFur.com |
de 1 à 10 Go |
de 50 à 500 Go |
PHP 4, 5 + Rails + Python + Perl 5 |
MySQL |
à partir de $4.95 |
30 jours de garantie |
OCS
Solutions |
de 1 à 20 Go |
de 5 à 50 Go |
PHP 4, 5 + Rails + Python 2.4 + Perl 5.8 |
MySQL 5 + PostgreSQL 7, 8 + SQLite 3 |
à partir de $6.95 |
Nom de domaine inclus dans l'offre annuelle |
WebFaction |
de 2 à 12 Go |
de 200 à 800 Go |
PHP + Rails + django |
MySQL + PostgreSQL |
à partir de $7.50 (pour 2 ans) ; $8.50 (1 an) |
- |
ThinkHost |
40 Go |
200 Go |
PHP 4 + Rails + Perl 5 + Python |
MySQL |
à partir de $5.95 |
- |
HostGator |
de 50 à 200 Go |
de 200 Go à 2 To |
PHP 4, 5 + Rails + Perl + Python |
MySQL |
à partir de $6.95 |
30 jours de garantie |
HostMonster |
300 Go |
3 To |
PHP 4 ou 5 + Rails 1.1 + Perl 5 + Python |
MySQL + PostgreSQL |
à partir de $5.95 |
Nom de domaine inclus |
Lunarpages.com |
350 Go |
3.5 To |
PHP + Rails + Perl + Python + ASP + JSP |
MySQL + PostgreSQL |
à partir de $6.95 |
Nom de domaine offert à vie pour l'offre de 12 ou 24 mois |
Hub.Org |
de 256 Mo à 16 Go |
de 1 à 512 Go |
PHP + Rails + Perl + Python (django) + Tomcat |
MySQL + PostgreSQL |
à partir de $5.99 |
Nom de domaine non inclus |
XMG
Hosting |
de 20 à 50 Go |
de 500 à 750 Go |
PHP 4, 5 + Rails + Perl + Python 2 |
MySQL |
à partir de $7.95 (pour 2 ans) |
- |
Dewahost |
de 200 Mo à 2 Go |
de 10 à 40 Go |
PHP 4, 5 + Rails + Perl + Python |
MySQL |
à partir de $8.95 |
- |
Voxxit Hosting |
de 5 à 25 Go |
de 20 à 100 Go |
PHP 5 + Rails 1.2 + Perl 5.8 + Python 2.4 |
MySQL 5 |
à partir de $7.99 |
- |
AxisHOST |
de 750 Mo à 10 Go |
de 10 à 175 Go |
PHP + Rails + Perl |
MySQL |
à partir de $5.99 |
- |
DownTownHost |
de 5 à 15 Go |
de 100 à 300 Go |
PHP 4, 5 + Rails + Perl 5.8 |
MySQL 4 ou 5 + PostgreSQL 8 |
à partir de $4.95 (pour 3 ans) ; $5.95 (2 ans) ; $7.95 (1
an) |
30 jours de garantie |
DinoHost |
de 2 à 6.5 Go |
de 100 à 330 Go |
PHP 4, 5 + Rails |
MySQL |
à partir de $5.99 |
- |
GrokThis.net |
de 1 à 3 Go |
de 15 à 60 Go |
PHP 4, 5 + Rails + django |
MySQL 4, 5 + PostgreSQL 7, 8 + SQLite 3 + Microsoft SQL 2005 +
Firebird |
à partir de $6 |
Nom de domaine non inclus |
JaguarPC |
17 Go |
210 Go |
PHP 4, 5 + Rails + Python + Perl + C/C++ |
MySQL |
à partir de $7.97 (pour 2 ans) ; $8.97 (1 an) |
Nom de domaine non inclus |
WebOnce |
de 1.5 à 6 Go |
de 20 à 100 Go |
PHP 4, 5 + Rails + Python + Perl |
MySQL |
à partir de $6.95 |
Nom de domaine non inclus |
TheSitePeople.com |
de 500 Mo à 5 Go |
de 2 à 80 Go |
PHP 4, 5 + Rails |
MySQL 4 |
à partir de $1.67 (pour 1 an) |
Nom de domaine non inclus |
Steelpixel |
de 1 à 8 Go |
de 15 à 80 Go |
PHP 5 + Rails 1.1 + Perl 5.8 + Python 2.3 |
MySQL 4.1 + PostgreSQL 7.4 |
à partir de $4 |
Nom de domaine non inclus. 30 jours de garantie |
GeekStorage.com |
de 1 à 7 Go |
de 20 à 120 Go |
PHP 4, 5 + Rails + Perl 5.8 + Python 2.2 |
MySQL + PostgreSQL |
à partir de $3.95 (pour 2 ans) ; $4.95 (1 an) |
Nom de domaine non inclus. 30 jours de garantie |
NotJustNothing
[De] |
de 50 Mo à 1 Go |
de 1 à 4 Go |
PHP + Rails + Perl + Python |
MySQL + PostgreSQL |
à partir de 1.50 Euros |
Nom de domaine inclus |
PeconiHosting.com |
de 500 Mo à 5 Go |
de 5 à 30 Go |
PHP 4, 5 + Rails |
MySQL + PostgreSQL |
à partir de $3.95 |
Nom de domaine non inclus |
Network
Redux |
de 10 à 20 Go |
de 250 à 500 Go |
PHP 4, 5 + Rails 1.2 + Perl + Python |
MySQL 4.1 + PostgreSQL 7.4 |
à partir de $7.95 (pour 1 an) |
Nom de domaine non inclus. 30 jours de garantie |
Host
MG |
de 1 à 3 Go |
de 25 à 35 Go |
PHP 4 + Rails + Tomcat (JSP) + Perl |
MySQL |
à partir de $6.95 |
Nom de domaine non inclus |
Blackcurrant
Hosting |
de 500 Mo à 2 Go |
de 10 à 40 Go |
PHP 5.1 + Rails 1.1 |
MySQL + PostgreSQL |
à partir de $6.95 |
Nom de domaine non inclus |
Squidhost.com |
de 50 Mo à 6 Go |
de 2 à 100 Go |
PHP 5 + Rails + Java + Perl |
MySQL + PostgreSQL |
à partir de $1.99 ; $0.99 (pour 1 an) |
- |
MavenHosting |
50 Go |
de 135 Go à 1 To |
PHP 4.4, 5.2 + Rails |
MySQL 4.1, 5 |
à partir de 4.99 Euros |
Nom de domaine inclus |
AlsaConcept.fr |
50 Mo |
5 Go |
PHP 4 + Rails + mod_perl + mod_python |
MySQL 4 |
à partir de 1.25 Euros |
Nom de domaine non inclus |
alwaysdata |
à partir de 100 Mo |
illimité |
PHP 4, 5 + Ruby 1.8 (et Rails) + Python 2.4, 2.5 (et django) +
Perl 5.8 |
MySQL 5 + PostgreSQL 8.1 |
à partir de 5 Euros |
Nom de domaine non inclus |
Si vous connaissez d'autres hébergeurs supportant Rails,
signalez-le afin que je les rajoute à cette liste. Cette liste
n'étant pas exhaustive, vous pouvez sans doute en trouver d'autres
ici :
Guide-Hébergeur.fr.
C'était pas la
mer à boire, hein ? Pour ceux qui sont encore en état de
coder : faites nous de beaux programmes et de beaux sites !
N'hésitez surtout pas à commenter ce tuto, c'est toujours
encourageant.
Vous aussi, contribuez à la documentation Ruby sur
Polydoc.org (à consulter sans
modération).