Apprendre a Programmer Avec Ruby

Embed Size (px)

Citation preview

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    1/79

    Christopher David PINE

    APPRENDRE PROGRAMMER

    Traduction de Jean-Pierre ANGHEL

    1

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    2/79

    APPRENDRE PROGRAMMERUn tutoriel pour les futurs programmeurs

    Table des matires

    0 - Avant-propos ....................................................................3

    1 - Les nombres .....................................................................7

    2 - Les lettres .......................................................................10

    3 - Variables et affectations .................................................14

    4 Mlangeons-les .............................................................16

    5 - O on en apprend plus sur les mthodes ......................20

    6 - Contrles de flux ............................................................29

    7 - Tableaux et itrateurs .....................................................37

    8 - Ecrire vos propres mthodes ........................................42

    9 - Les classes .....................................................................56

    10 - Blocs et procdures ......................................................67

    11 - Au del de ce tutoriel.....................................................75

    12 - Au sujet de ce tutoriel....................................................78

    13 Notes sur la version franaise......................................79

    2

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    3/79

    Avant propos

    Si vous voulez programmer un ordinateur, vous devez "parler" dans une langue que votremachine comprendra : un langage de programmation. Il existe de nombreux langages de

    ce type, et certains sont mme excellents. Dans ce tutoriel jai choisi dutiliser monlangage de programmation favori, Ruby.

    Avant d tre mon langage prfr, Ruby est aussi le langage le plus facile que jaie jamaisvu (et jen ai vu quelques-uns croyez-moi). En fait, la raison principale pour laquelle jaicrit ce tutoriel est la suivante : je nai pas dcid dcrire un tutoriel et choisi Ruby parceque cest mon langage favori; jai trouv Ruby si facile que jai pens quil irait trs biencomme tutoriel pour dbutant. Cest la simplicit de Ruby qui ma incit crire ce tutorielet non le fait quil soit mon favori. (Ecrire un tutoriel identique pour un autre langage, C++ou Java, ncessiterait des centaines et des centaines de pages). Mais nallez pas penserque Ruby nest qu un langage pour dbutant parce quil est facile ! Cest un puissant et

    robuste langage de programmation professionnel sil en fut.

    Quand vous crivez quelque chose dans une langue humaine, ce que vous crivez estappel texte. Quand vous crivez quelque chose dans un langage de programmation, ceque vous crivez est appel code. Jai inclus plusieurs exemples tout au long de cetutoriel, la plupart dentre eux tant des programmes complets que vous pourrez excutersur votre ordinateur. Pour rendre le code plus facile lire, jai color le code de couleursdiffrentes. (Par exemple, les nombres sont toujours en vert). Ce que vous tes censstaper est dans une

    bote grise

    et ce que le programme renvoie dans une

    bote bleue.

    Sil y a quelque chose que vous ne comprenez pas, ou si vous avez une question quidemeure sans rponse, gardez-la sous le coude et attendez davoir fini votre lecture ! Il estfort possible que la rponse se trouve dans le chapitre suivant. Toutefois si la fin dudernier chapitre vous navez toujours rien vu venir, je vous dirai qui questionner. Il y a denombreuses personnes capables de vous aider, il suffit juste de savoir o les trouver.

    Mais nous devons tout dabord tlcharger Ruby et linstaller sur votre ordinateur.

    3

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    4/79

    Installation sous Windows

    Linstallation de Ruby sous Windows est enfantine. Vous devez premirement tlchargerRuby (http://rubyinstaller.sourceforge.net/) . Vous aurez sans doute le choix entre deux

    versions ; ce tutoriel a t fait avec la version 1.8.0, aussi assurez-vous de tlcharger laversion la plus rcente. (Je voulais juste indiquer la dernire version disponible). Ensuitelaissez-vous guider par le programme dinstallation. Il vous sera demand dans quelrpertoire vous voulez installer Ruby. Choisissez de prfrence le rpertoire par dfaut, moins que vous nayez dexcellentes raisons de ne pas le faire.

    Pour programmer, vous devez tre capable dcrire et d excuter un programme. Pour cefaire vous devez avoir un diteur de texte et une ligne de commande.

    Linstallation de Ruby fournit un traitement de texte appel SciTE (pour Scintilla TextEditor) . Vous pouvez excuter SciTE partir de la fentre de commande de Ruby dans lemenu Dmarrer. SciTE vous permettra d'une part d'avoir du code color comme dans cetutoriel, et d'autre part vous vitera de taper chaque essai ruby + le nom duprogramme, un appui sur la touche F5 (ou 'Outils/Excuter', dans le menu) fera tout cela votre place, le rsultat s'affichant dans la partie droite de l'diteur.

    Ce sera aussi une bonne ide que de crer un rpertoire pour sauvegarder tous vosprogrammes. Assurez-vous toujours quand vous sauvegardez un programme que voustes bien dans le bon rpertoire.

    Pour obtenir votre ligne de commande (dans une fentre noire), slectionnez : Pour Windows 98 : Dmarrer puis Programmes puis Accessoires et enfin

    Commandes MSDos. Pour Windows XP : dmarrer puis Programmes puis Accessoires et enfin Invite de

    commandes.

    Vous devrez ensuite naviguer jusquau rpertoire o sont entreposs vos programmes.Taper

    cd..

    vous fait remonter dun niveau dans la hirarchie des rpertoires.

    Et tapercd nom_rpertoire

    vous conduit directement o vous voulez.

    Pour voir tous les rpertoires inclus dans le vtre tapez :dir /ad

    4

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    5/79

    Installation sur Macintosh

    Si vous possdez Mac OS X 10.2 (Jaguar) vous avez dj Ruby sur votre systme ! Quedemander de plus ? Si vous avez la version 10.1, vous devez tlcharger Ruby. Et simalheureusement pour vous, vous tes encore sous Mac OS 9 ou une version encore

    plus ancienne, je ne pense pas que vous puissiez utiliser Ruby.

    Pour programmer, vous devez tre capable dcrire et d excuter un programme. Pour cefaire vous devez avoir un diteur de texte et une ligne de commande.

    Votre ligne de commande est accessible par lapplication Terminal (dansApplications/Utilitaires)

    Comme diteur de texte utilisez celui avec lequel vous vous sentez le plus l aise. Sitoutefois vous utilisez TextEdit, assurez-vous lors des sauvegardes que vous tes en texteseulement ! Sinon vos programmes ne fonctionneront pas. Dautres options accessibles

    de la ligne de commande sont emacs, vi et pico.

    Installation sous Linux

    Premirement, vrifiez que Ruby nest pas dj install sur votre systme ! Tapez :which ruby

    Si vous obtenez une rponse du style

    /usr/bin/which: no ruby in ()

    vous devez alors tlcharger Ruby, sinon vrifiez la version de Ruby en tapantruby -v

    Si votre version est infrieure celle propose sur le site de tlchargement, chargezdonc la nouvelle version.

    Si vous tes l'administrateur (root), vous n'aurez certainement besoin d' aucune instructionpour installer Ruby. Dans le cas contraire, vous devez demander votre administrateursystme de faire l'installation pour vous (ceci afin que quiconque sur ce systme puisseutiliser Ruby).Sinon, vous pouvez l' installer comme seul utilisateur. Dplacez le fichier que vous aveztlcharg dans un rpertoire temporaire, par exemple $HOME/tmp. Si le nom du fichierest ruby-1.6.7.tar.gz, vous pouvez l'ouvrir par

    tar zxvf ruby-1.6.7.tar.gz

    Changez de rpertoire pour celui que vous venez de crer. Dans cet exemple :cd ruby-1.6.7

    Configurez votre installation en tapant :

    ./configure --prefix=$HOME

    5

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    6/79

    puis tapez :make

    ce qui construira votre interprteur. Ceci peut prendre quelques minutes. Une fois termintapez :

    make install

    pour l'installer.

    Ensuite vous devez ajouter $HOME/bin votre commande de recherche de chemin enditant le fichier $HOME/.bashrc (vous devez quitter la session et re-entrer pourque ceci soit pris en compte). Aprs ceci testez votre installation :

    ruby -v

    Si vous obtenez une rponse vous indiquant le numro de version, vous pouvez alorseffacer les fichiers dans le rpertoire $HOME/tmp ( o l o vous les aviez mis).

    6

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    7/79

    1. Les Nombres

    Maintenant que nous avons tout install, nous allons crire un programme. Ouvrez votrediteur de texte favori et tapez ce qui suit:

    puts 1+2

    Sauvez votre programme (si, si c'est un programme !) sous le nom p7.rb ('.rb' c'est ce quenous mettons habituellement la fin du nom d'un programme en Ruby), p7 cest lenumro de la page, comme cela vous pourrez facilement retrouver vos exemples.Maintenant excutez votre programme en tapant:ruby p7.rb (ou bien F5 dans SciTE)

    dans votre ligne de commande. Vous devez obtenir un 3 sur votre cran. Vous voyez,programmer n'est pas si difficile, n'est ce pas ?

    Introduction puts

    Que va donc faire ce programme ? Je suis sr que vous avez devin ce que donnera 1+2;votre programme est en fait quivalent

    puts 3

    puts (de put : mettre, poser) crit simplement tout ce qui le suit.

    Entiers et rels

    Dans la plupart des langages (et Ruby ne fait pas exception) les nombres sans virgulesont appels des entiers, et ceux avec une virgule des rels. Attention, comme sur lescalculettes, la virgule franaise est remplace par un point !

    Voici quelques entiers :

    5-205

    99999999999999999999999990

    et voici quelques rels :

    54.3210.001-205.38840.0

    En pratique les programmes n'utilisent pas de rels; seulement des entiers. (Aprs tout,personne ne va regarder 7,4 courriels, ou faire dfiler 1,8 pages du Web, ou couter 5,24

    7

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    8/79

    morceaux de musique...). Les rels sont utiliss plutt pour desapplications acadmiques(expriences de physique etc...) et pour les graphiques 3D. Mme les programmesfinanciers utilisent des entiers; ils gardent seulement trace du nombre de centimes !

    Arithmtique simple

    Bon, nous avons tout ce qu'il faut pour simuler une calculatrice. Les calculatrices utilisentles rels, donc si nous voulons que notre ordinateur ragisse comme elles, nous devonsutiliser les rels. Pour les additions et les soustractions, nous utiliserons les signes '+' et '-'.Pour les multiplications et les divisions les signes '*' et '/'. La plupart des clavierspossdent ces touches sur le clavier numrique . Sur les mini-claviers et les portables ilfaut les rechercher sur le clavier normal en utilisant la touche 'Shift' (la flche vers le haut)simultanment. Modifions maintenant un peu notre programme en p8.rb. Tapez ce qui suitet faites excuter chaque ligne :

    puts 1.0 + 2.0puts 2.0 * 3.0puts 5.0 - 8.0puts 9.0 / 2.0

    ce qui vous retournera :

    3.06.0-3.04.5

    (les espaces dans le programme ne sont pas importants; ils rendent tout simplement lecode plus lisible.) La virgule franaise est remplace par un point ! Bien, part a, il n'y apas de surprises. Essayons maintenant avec des entiers :

    puts 1+2puts 2*3puts 5-8puts 9/2

    A premire vue c'est pareil, non ?

    36-34

    Zut, le dernier ne donne pas le mme rsultat ! Et bien quand vous calculez avec desentiers vous obtenez des rponses en entiers. Quand l'ordinateur ne peut pas donner la"bonne" rponse, il arrondit toujours le rsultat. (Bien sr, 4 est la bonne rponse enarithmtique entire pour 9/2; il se peut cependant que ce ne soit pas la rponse

    laquelle vous vous attendiez.)

    8

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    9/79

    Peut-tre vous demandez-vous quoi servent les entiers. Imaginez que vous ayez 9euros et que vous dsiriez voir des films dans un cinma 2 euros la sance (NDT:l'exemple est amricain, cela va de soit ! ) Combien pourrez-vous voir de films ? 4,5 n'estdcidment pas la bonne rponse dans ce cas; on ne vous laissera pas voir la moiti d'unfilm ni payer la moiti du prix pour voir un film entier... certaines choses ne sont pas

    divisibles.

    Essayez donc maintenant de faire des exemples tout seul. Si vous voulez vous pouvezutiliser des expressions complexes et utiliser des parenthses. Par exemple :

    puts 5 * (12-8) + -15puts 98 + (59872 / (13*8)) * -52

    5-29802

    Quelques petits trucs essayer

    Ecrivez un programme qui vous dise : combien d'heures y a-t-il dans une anne. combien de minutes dans une dcennie. de combien de secondes tes-vous g(e). combien de chocolat esprez-vous manger durant votre vie.Attention : cette partie de programme risque de prendre un certain temps de calcul !

    Ici une question plus difficile : Si je suis g de 870 millions de secondes, quel ge ai-je ?

    9

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    10/79

    2. Les lettres

    Bien, nous avons tout appris des nombres, mais qu'en est-il des lettres, des mots, dutexte?

    Nous nous rfrerons un groupe de lettres dans un programme, comme une chanede caractres. (Vous pouvez penser des lettres que l'on rajoute les unes aprs lesautres sur une bannire). Pour rendre plus visibles les parties de code qui sont deschanes de caractres, je vais les mettre en rouge. Voici quelques exemples :

    'Coucou''Ruby marche fort.''5 est mon nombre favori...quel est le vtre ?''Snoopy dit #%^&*@ quand il se cogne le pied.'' '

    ''

    Comme vous pouvez le voir, les chanes de caractres peuvent contenir de laponctuation, des chiffres, des symboles et des espaces en plus des lettres. La dernirechane n'a rien l'intrieur, nous dirons que c'est une chane vide.

    Nous avons utilis puts pour crire des nombres; essayons avec quelques chanes decaractres :

    puts 'Coucou'puts ''

    puts 'au revoir.'

    Coucou

    au revoir.

    Cela "marche" bien. Maintenant essayez des chanes de votre cru.

    Chanes arithmtiques

    De la mme faon que vous faites de l'arithmtique avec des nombres, vous pouvez enfaire avec des chanes ! Enfin, quelque chose qui y ressemble. Essayons d'additionnerdeux chanes et voyons ce que fait puts dans ce cas.

    puts 'Mon fromage prfr est' + 'le roquefort.

    Mon fromage prfr estle roquefort.

    Oups! J'ai oubli un espace entre 'est' et 'le'. Les espaces sont habituellement sansimportance, mais dans le cas des chanes si. C'est vrai ce que l'on dit : les ordinateurs nefont pas ce que vous voudriez qu'ils fassent, mais seulement ce que vous leur dites de

    faire.)

    10

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    11/79

    Essayons encore :

    puts 'Mon fromage prfr est ' + 'le roquefort.'puts 'Mon fromage prfr est' + ' le roquefort.'

    Mon fromage prfr est le roquefort.Mon fromage prfr est le roquefort.

    (Comme vous pouvez le voir, l'endroit o j'ai rajout l'espace n'a pas d'importance.)

    Si vous pouvez ajouter des chanes vous pouvez aussi les multiplier (par un nombre):

    puts 'pim ' * 3

    pim pam poum

    Non, je rigole... en ralit on obtient :

    pim pim pim

    En fait si vous rflchissez, cela est logique. Aprs tout, 7*3 signifie 7+7+7, ainsi 'miaou' *3 signifie simplement 'miaou' + 'miaou' + 'miaou'.

    12 versus'12'

    Avant d'aller plus loin, il vaut mieux tre sr que vous faites bien la diffrence entrenombres et chiffres. 12 est un nombre, mais '12' est une chane de caractres de deuxchiffres.Insistons encore un peu :

    puts 12 + 12puts '12' + '12'puts '12 + 12'

    241212

    12 + 12

    et que pensez-vous de cela :

    puts 2 * 5puts '2' * 5puts '2 * 5'

    1022222

    2 * 5

    11

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    12/79

    Ces exemples sont bien sr trs simples. Cependant, si vous ne faites pas trs attentionlorsque vous mlangez des chanes de caractres et des nombres, vous pouvez voustromper...

    Problmes

    A ce stade vous avez peut-tre dcouvert des choses qui ne fonctionnaient pas. Dans lecas contraire, voici tout de mme quelques exemples de ce qui peut arriver :

    puts '12' + 12puts '2' * '5'

    p12.rb:1:in `+': failed to convert Fixnum into String (TypeError)from p12.rb:1

    Ae... un message d'erreur. Le problme vient de ce que vous ne pouvez pas ajouter unnombre une chane, ou multiplier une chane par une autre chane. Cela n'a pas plus desens que :

    puts 'Betty' + 12puts 'Fred' * 'Jean'

    Encore un autre cas pour montrer l'importance de l'ordre d'criture : vous pouvez crire'pim' * 5 dans un programme, puisque cela signifie seulement que vous allez ajouter 5 foisla chane 'pim'. Par contre, vous ne pouvez pas crire 5 * 'pim', ce qui voudrait dire 'pim'fois le chiffre 5, ce qui ne veut rien dire.

    Finalement, si je veux crire un programme qui affiche 'J'ai faim !', essayons comme cela :

    puts 'J'ai faim !'

    Bon, a ne "marche" pas. Je ne peux mme pas l'excuter. L'ordinateur pense que nousen avons termin avec la chane lorsqu'il rencontre la deuxime apostrophe. (D'ol'avantage d'utiliser un diteur de texte qui colorie la syntaxe pour vous !). Comment fairepour indiquer l'ordinateur que la chane continue ? Nous devons supprimer l'action del'apostrophe comme ceci :

    puts 'J\'ai faim !'

    J'ai faim !

    Le caractre "\" est le caractre d'chappement. Ce qui signifie que, si vous avez un "\" etun autre caractre, ils sont parfois transforms en un autre caractre. Les seules chosesque "\" modifie sont l'apostrophe et "\" lui-mme.

    Quelques exemples pour mieux comprendre :

    12

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    13/79

    puts 'J\'ai faim !'puts ' la fin d\'une chane : \\'puts 'oui\\non'puts 'oui\non'

    J'ai faim ! la fin d'une chane : \oui\nonoui\non

    Puisque "\" n'a pas d'influence sur un "n", mais sur lui-mme oui, les deux derniersexemples sont quivalents. Ils ne paraissent pas les mmes dans votre code, mais pourl'ordinateur ils sont identiques.

    13

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    14/79

    3. Variables et affectations

    Jusqu' prsent, tout ce que nous avons "puts" c'est une chane ou un nombre, mais ceque nous avons "puts" a disparu. Ce que je veux dire c'est que si nous voulons afficherquelque chose deux fois l'cran, nous devons le taper deux fois :

    puts '... vous pouvez rpter...'puts '... vous pouvez rpter...'

    ... vous pouvez rpter...

    ... vous pouvez rpter...

    Ce qui serait bien, c'est si l'on pouvait juste taper une chose une fois, la prendre et ... lastocker quelque part. Bien sr, nous le pouvons, sinon je n'aurais pas pos la question !

    Pour stocker la chane dans la mmoire de l'ordinateur, nous devons donner un nom lachane. Les programmeurs disent qu'ils affectentune valeur, et appellent les noms desvariables. Ces variables peuvent tre des squences de lettres ou bien de chiffres, mais lepremier caractre est obligatoirement une minuscule. Essayons ceci dans le programmeprcdent, mais ce stade il faut donner un nom la chane. Pourquoi pas 'maChaine'(que l'on pourrait tout aussi bien appeler chat ou maToutePetiteChaine ou encorelouisQuatorze)

    maChaine = '...pouvez-vous rpter...'puts maChaineputs maChaine

    ...pouvez-vous rpter...

    ...pouvez-vous rpter...

    Chaque fois que vous essayez de faire quelque chose avec maChaine, le programmevous retourne '...pouvez-vous rpter...'. On peut imaginer que la variablemaChaine "pointe" sur la chane '...pouvez-vous rpter...'. Voici un exempleplus intressant :

    nom = 'Hubert de La PteFeuillete'puts 'Mon nom est ' + nom + '.'

    puts 'Ouf! ' + nom + ' est vraiment un nom long!'Mon nom est Hubert de La PteFeuillete.Ouf ! Hubert de La PteFeuillete est vraiment un nom long!

    Bon, de la mme faon que nous pouvons affecterun objet une variable, nous pouvonsr-affecterun objet diffrent cette variable. (C'est pour cela que nous les appelons desvariables : parce que ce qu'elles "pointent" (dsignent) peut varier.)

    compositeur = 'Mozart'

    puts compositeur + ' tait "une vedette", en son temps.'compositeur = 'Beethoven'

    14

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    15/79

    puts 'Mais je prfre ' + compositeur +', personnellement.'

    Mozart tait "une vedette", en son temps.Mais je prfre Beethoven, personnellement.

    Bien entendu les variables peuvent pointer vers d'autres choses que des chanes decaractres :

    var = 'juste une autre ' + 'chane'puts var

    var = 5 * (1 + 2)puts var

    juste une autre chane15

    En fait les variables peuvent pointer sur n'importe quoi ... except sur d'autres variables.Mais que se passe-t-il si nous essayons ceci :

    var1 = 8var2 = var1puts var1puts var2

    puts ''

    var1 = 'Huit'puts var1puts var2

    88

    Huit8

    Dans le premier cas, quand nous essayons de faire pointervar2 vers var1, en ralitnous pointons sur 8 (juste parce ce que var1 pointait sur 8). Ensuite nous avons var1 qui

    pointe sur 'Huit', mais puisque var2 n'a jamais rellement point vers var1, elle restesur 8.

    15

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    16/79

    4. Mlangeons-les

    Nous avons vu diffrentes sortes d'objets (nombres et lettres), et nous avons fabriqu desvariables pour pointer vers eux; la prochaine tape vise jouer, le plus agrablementpossible, avec tout ces objets ensemble.

    Nous avons vu que si nous voulons crire un programme pour crire 25, ce qui suit nemarche pas, parce que nous ne pouvons pas additionner des nombres et des chanes decaractres :

    var1 = 2var2 = '5'

    puts var1 + var2

    Une partie du problme provient du fait que votre ordinateur ne comprend pas si vousvoulez obtenir 7 (2 + 5), ou bien 25 ('2' + '5').

    Avant de pouvoir les additionner ensemble, nous devons trouver un moyen d'obtenir laversion chane de var1, ou bien la version nombre de var2.

    Conversions

    Pour obtenir la version chane de caractres d'un objet, il suffit d'crire.to_s sa suite (spourstring; .to_s= transforme en chane).

    var1 = 2var2 = '5'

    puts var1.to_s + var2

    De la mme faon,to_i donne la version nombre (entire) d'un objet (i pourinteger), etto_f la version nombre rel (f pourfloat). Voyons d'un peu plus prs ce que donnent cestrois mthodes:

    var1 = 2

    var2 = '5'

    puts var1.to_s + var2puts var1 + var2.to_i

    257

    Notons que mme aprs avoir obtenu la version chane devar1en appelant to_s, var1pointait toujours sur2, et jamais sur '2'. A moins que nous rassignions var1 (ce quincessite le signe =), la variable pointera sur2 durant toute la dure du programme.

    Essayons maintenant quelques conversions intressantes (pour ne pas dire tranges) :

    16

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    17/79

    puts '15'.to_fputs '99.999'.to_fputs '99.999'.to_iputs ''

    puts '5 est mon chiffre favori !'.to_iputs 'Qui vous parle de 5 ?'.to_iputs 'votre maman le faisait'.to_fputs ''puts 'bizarre'.to_sputs 3.to_i

    15.099.99999

    5

    00.0

    bizarre3

    Bon, il y a quelques surprises. La premire rponse tait prvisible et donne 15.0. Aprsa, nous convertissons la chane '99.999' en un nombre rel puis en un entier.to_f a fait ce que nous attendions; to_i a arrondi la valeur entire immdiatementinfrieure.

    Ensuite, nous avons quelques exemples de chanes inhabituelles converties en nombres.to_i ignore la premire chose qu'il ne comprend pas, et le reste de la chane partir dece point. Ainsi la premire chane a t convertie en 5, mais les autres, puisqu'ellesdbutent par une lettre, sont totalement ignores... l'ordinateur choisit simplement derpondre par un 0.

    Finalement, nous nous rendons compte que les deux dernires conversions ne font riendu tout, comme on pouvait s'y attendre.

    Un autre regard surputs

    Il y a tout de mme quelque chose d'trange dans notre mthode favorite... jetez un coupd' oeil sur ce qui suit :

    puts20puts 20.to_sputs '20'

    202020

    17

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    18/79

    Pourquoi diable ces trois-l impriment-ils la mme chose ? Bon, les deux derniers a secomprend, puisque 20.to_s est bien '20'. Mais qu'en est-il du premier, l'entier20? Dansce cas, que signifie crire l'entier20? Quand vous crivez un 2 et ensuite un 0 sur unefeuille de papier, vous crivez une chane de caractres et non un entier. L'entier20 est lenombre de doigts et d'orteils que j'ai; ce n'est pas un 2 suivi d'un 0.

    Bien, il est temps de dvoiler le grand secret de notre ami puts : avant queputs tented'crire un objet, il utiliseto_s pour obtenir la version chane de cet objet. En fait, le s deputsest mis pourstring(chane en anglais);putsen ralit signifieput string (exprimer,mettre en chane)

    Ceci peut vous paratre peu intressant, mais il y a une multitude d'objets dans Ruby (etvous allez mme apprendre crer les vtres !), et il est intressant de savoir ce qui sepasse lorsque vous tentez d'appliquer la mthode puts un objet trange, tel qu'unephoto de votre grand-mre, ou un fichier musical etc... Mais cela viendra plus tard...

    En attendant, nous avons quelques mthodes pour vous, et elles vont nous permettrentd'crire toutes sortes de programmes sympathiques.

    Les mthodes getsetchompSi puts signifie put string, je suis sr que vous devinerez ce que veut dire gets (get =obtenir). Et de la mme faon que puts affiche toujours des chanes, gets renverraseulement des chanes. Et d'o les obtiendra-t-il ?

    De vous ! Bon, de votre clavier, bien sr. Et puisque votre clavier fabrique seulement deschanes, c'est parfait. Ce qu'il se passe actuellement c'est que gets lit tout ce que voustapez jusqu' ce que vous appuyiez sur la touche Enter. Essayons ceci :

    puts gets

    Y a-t-il un cho ici ?Y a-t-il un cho ici ?

    Bien sr, tout ce que vous tapez est rpt aprs vous. Excutez-le quelques fois etessayez diffrentes choses.

    Maintenant nous pouvons faire des programmes interactifs ! Dans celui-ci, entrez votrenom et il vous rpondra :

    puts 'Bonjour, quel est donc votre nom ?'monnom = getsputs 'Votre nom est ' + monnom + '? Quel joli nom !'puts 'Ravi de faire votre connaissance ' + monnom + '. :)'

    Ae! J'excute -j'entre juste mon nom - et voici ce qui s'affiche :

    18

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    19/79

    Bonjour, quel est donc votre nom ?ChristianVotre nom est Christian? Quel joli nom !Ravi de faire votre connaissance Christian

    . :)

    Hmmm...il semble que lorsque je tape les lettres C,h,r,i,s,t,i,a,n et presse ensuite

    la touche Enter, gets renvoie toutes les lettres de mon nom mais aussi la touche

    Enter! Heureusement il existe une mthode pour ce genre de choses : chomp. Elleenlve toutes les frappes de la touche Enter qui peuvent suivre votre chane. Essayons leprogramme de nouveau, mais avec chomp (mastiquer) pour nous aider :

    puts 'Bonjour, quel est donc votre nom ?'monnom = gets.chomp

    puts 'Votre nom est ' + monnom + '? Quel joli nom !'puts 'Ravi de faire votre connaissance ' + monnom + '. :)'

    Bonjour, quel est donc votre nom ?ChristianVotre nom est Christian? Quel joli nom !Ravi de faire votre connaissance Christian. :)

    Voil qui est mieux ! Notons que puisquemonnom pointe vers gets.chomp, nousn'avons pas eu diremonnom.chomp; monnomtait dj chomp.

    Quelques petites choses essayer

    Ecrire un programme qui demande une personne son premier prnom, sondeuxime, et enfin son nom de famille. En sortie le programme devra fliciter lapersonne en utilisant son identit complte.

    Ecrire un programme qui demande une personne son nombre favori. Votreprogramme devra ajouter un ce nombre, et proposer le rsultat comme tant plusgrand et donc meilleur pour un favori (Dites-le tout de mme avec tact !).

    Lorsque vous aurez achev ces deux programmes (et plus si vous dsirez en essayerd'autres), nous apprendrons d'autres mthodes (et un peu plus sur les mthodes en

    gnral).

    19

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    20/79

    5. O on en apprend plus sur les mthodes

    Nous avons vu un certain nombre de mthodes, puts et gets et d'autres (Test surprise: donnez la liste des mthodes que nous avons dj vues ! Il y en a dix; la rponse est ci-

    dessous), mais nous ne nous sommes pas pos la question de savoir ce qu'taitexactement une mthode. Nous savons ce qu'elles font mais pas ce qu'elles sont.

    En ralit, c'estce qu'elles sont : des choses qui font . Si les objets (tels que chanes,entiers, rels) sont les noms dans le langage Ruby, alors les mthodes ressemblent desverbes. Et, comme en franais, vous ne pouvez avoir un verbe sans un nom ("sujet") pourl'excuter. Par exemple, sonner n'est pas le fait du hasard; le carillon (ou un autre engin)fait cela. En franais nous dirons, "Le carillon sonne". En Ruby nous dironscarillon.sonne (en supposant que carillon soit un objet Ruby, bien sr). Lesprogrammeurs disent alors qu'ils "appellent la mthode sonne de carillon".

    Bien, avez-vous fait le test surprise ? Je suis sr que vous vous souveniez des mthodesputs, gets et chomp, puisque nous venions juste de les voir. Vous n'avez probablement

    pas oubli nos mthodes de conversions, to_i, to_f et to_s.Cependant, avez-voustrouv les quatre autres ? pourtant ce ne sont que nos vieilles connaissancesarithmtiques +, -, * et / !

    Comme je l'ai dj dit, de la mme faon qu'un verbe ncessite un nom, une mthodencessite un objet. Il est habituellement facile de dire quel objet excute telle mthode :c'est celui qui prcde le point, comme dans notre exemple carillon.sonne, ou dans101.to_s. Ce n'est pas toujours aussi simple; comme avec les mthodes arithmtiques.Quand nous crivons 5 + 5, il s'agit en ralit du raccourci de 5.+ 5. Par exemple :

    puts 'Salut ' .+ 'les gars'puts (10.* 9).+ 9

    Salut les gars99

    Ce n'est pas trs joli, aussi ne l'crivons-nous jamais ainsi; cependant, il est important decomprendre ce qui se passe rellement. (Sur ma machine, j'ai droit un avertissement :warning: parenthesize argument(s) for future version (attention :argument(s) entre parenthses pour version future). Le code s'est bien excut mais on

    me prvient quil peut y avoir des difficults interprter ma pense, donc d'utiliser plusde parenthses dans le futur). Cela nous donne aussi une explication plus profonde sur lefait qu'on peut crire 'pim'*5 mais pas 5*'pim' : 'pim'*5 appelle 'pim' pour faire unemultiplication par 5, tandis que 5*'pim' appelle 5 pour faire une multiplication par'pim' !. 'pim' sait comment faire 5 copies de lui-mme et les ajouter ensemble, mais 5prouve de sacres difficults pour faire 'pim' copies de lui-mme et les additionner.

    Et bien sr nous avons puts et gets expliquer. O sont donc leurs objets? En franais,vous pouvez parfois omettre le nom; par exemple si on interpelle quelqu'un par "Viens !",le nom de celui qui est interpell est implicite pour lui. En Ruby, si je disputs 'Etre ou ne pas tre', ce que je suis en train de dire en ralit c'estself.puts 'Etre ou ne pas tre'. Mais qu'est-ce donc que ce self (moi-mme) ? C'est une variable spciale qui pointe sur un objet quelconque dans lequel vous

    20

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    21/79

    tes. Nous ne savons pas encore comment tre dans un objet, mais jusqu' ce que nousle trouvions, sachez que nous sommes toujours dans un grand objet qui est... leprogramme lui-mme en entier ! Et heureusement pour nous, le programme possdequelques mthodes en propre, telles que puts et gets. Observons ceci :

    jepeuxdonnerunnomdevariabletreslongpourpointersurun3 = 3puts jepeuxdonnerunnomdevariabletreslongpourpointersurun3sel.puts jepeuxdonnerunnomdevariabletreslongpourpointersurun3

    33

    Si vous n'avez pas entirement suivi tout ce qui prcde, c'est parfait. La choseimportante retenir de tout a est que toute mthode appartient un objet mme s'il n'y apas de point qui la prcde. Si vous avez compris cela, vous tes sur la bonne voie.

    Mthodes originales de chanes

    Voici quelques mthodes amusantes des chanes de caractres. Vous n'avez pas lesretenir toutes; vous pourrez toujours revenir cette page si vous les oubliez. Je veuxjuste vous montrer une petite partie de ce que peuvent faire les chanes. En fait, je ne suispas capable moi-mme d'en retenir ne serait-ce que la moiti, mais cela n'a aucuneimportance car on trouve sur Internet de nombreuses rfrences sur les mthodes dechanes avec toutes les explications ncessaires. (Je vous indiquerai la fin de ce tutorielo les trouver.)Vraiment, je nai pas besoin de connatre toutes les mthodes des chanes; ce serait

    comme connatre tous les mots du dictionnaire. Je suis capable de m'exprimercorrectement en franais sans pour cela en connatre tous les mots... et puis n'est-ce pastout l'intrt du dictionnaire ? Ainsi vous n'avez pas savoir ce qu'il y a dedans.

    Bon, notre premire mthode s'appelle reverse, et donne une version inverse d'unechane :

    var1 = 'stop'var2 = 'stressed'var3 = 'pouvez-vous prononcer ceci invers ?'

    puts var1.reverseputs var2.reverseputs var3.reverseputs var1puts var2puts var3

    potsdesserts? srevni icec recnonorp suov-zevuop'stopstressed

    pouvez-vous prononcer ceci invers ?

    21

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    22/79

    Comme vous le voyez, reverse n'inverse pas la chane d'origine; elle en fait seulementune nouvelle version inverse. C'est bien pour cela que var1 est bien gale 'stop'aprs l'appel de reverse survar1.

    Une autre mthode est length, qui nous renseigne sur le nombre de caractres

    composant la chane (espaces inclus) :

    puts 'Quel est votre nom complet ?'nom = gets.chompputs 'Savez-vous qu\' il y a ' + nom.length + ' caractres dansvotre nom, ' + nom + ' ?'

    Quel est votre nom complet ?Christopher David PineP22.rb:3:in '+' : cannot convert Fixnum into String (TypeError)

    from p22.rb:3

    Ae, ae, ae. Quelque chose ne marche pas, et cela semble se produire aprs la lignenom = gets.chomp... Voyez-vous le problme ? essayez de vous le reprsenter.

    Le problme est avec length : la mthode nous donne un nombre, mais il nous faut unechane. Facile, il nous suffit de rajouter un to_s (et de croiser les doigts) :

    puts 'Quel est votre nom complet ?'nom = gets.chompputs 'Savez-vous qu\' il y a ' + nom.length.to_s + ' caractresdans votre nom, ' + nom + ' ?'

    Quel est votre nom complet ?Christopher David PineSavez-vous qu' il y a 22 caractres dans votre nom, ChristopherDavid Pine ?

    Non, je ne le savais pas. Note : c'est le nombre de caractres dans mon nom, pas lenombre de lettres (comptez-les). Je propose que vous criviez un programme qui vousdemande vos nom et prnoms, individuellement, et les ajoute ensuite l'un la suite del'autre... H, pourquoi ne le faites-vous pas? Un peu de nerf, je vous attends.

    Alors, c'est fait ? Bien! N'est-ce pas que c'est agrable de programmer ? Encore quelqueschapitres et vous serez tonn(e) de ce que vous pouvez faire.

    Bien, il existe aussi des mthodes qui changent la casse de votre chane (majuscule etminuscule). upcase change chaque minuscule en majuscule, et downcase changechaque majuscule en minuscule. swapcase intervertit chaque lettre de la chane et, enfin,capitalize est comme downcase, sauf qu' elle met la premire lettre de la chane enmajuscule (si c'est une lettre).

    lettres = 'aAbBcCdDeE'puts lettres.upcase

    puts lettres.downcaseputs lettres.swapcase

    22

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    23/79

    puts lettres.capitalizeputs ' a'.capitalizeputs lettres

    AABBCCDDEEaabbccddeeAaBbCcDdEeAabbccddeeaaAbBcCdDeE

    Joli petit truc. Comme vous pouvez le voir dans la ligne puts ' a'.capitalize, lamthode capitalize ne met en majuscule que le premier caractre, non la premirelettre. Et le dernier exemple montre, comme nous l'avons dj vu, que l'appel de toutesces mthodes ne change pas la variable lettres. Je sais que je rabche, mais il estimportant de comprendre cela.

    Il existe des mthodes qui modifient l'objet associ, mais nous ne les verrons pas encore,et cela pour un bout de temps.

    Les dernires mthodes originales que nous allons voir concernent le formatage visueldes chanes. La premire, center, ajoute des espaces au dbut et la fin pour centrer lachane. Cependant, de la mme faon que vous appelez puts pour ce que vous voulezafficher, et + pour ce que vous voulez lui ajouter, vous appellerez center pour centrerune chane suivant vos dsirs. Ainsi si je souhaite centrer les lignes d'un pome, je doisfaire quelque chose dans le style :

    largeurLigne = 50

    puts ( 'Une souris verte'.center(largeurLigne))puts ('Qui courrait dans l\'herbe'.center(largeurLigne))puts ('Je l\'attrape par la queue'.center(largeurligne))puts ('Je la montre ce monsieur'.center(largeurLigne))puts ( 'Ce monsieur me dit'.center(largeurligne))puts ( 'Trempez-la dans l\'huile'.center(largeurLigne))puts ( 'Trempez-la dans l\'eau'.center(largeurligne))puts ( 'Ca fera un escargot'.center(largeurLigne))puts ( 'Tout chaud'.center(largeurligne))

    Une souris verteQui courrait dans l'herbeJe l'attrape par la queueJe la montre ce monsieur

    Ce monsieur me ditTrempez-la dans l'huileTrempez-la dans l'eauCa fera un escargot

    Tout chaud

    23

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    24/79

    Hmmm...Je ne suis pas vraiment sr que la comptine sois juste, mais j'ai la flemme devrifier. (Je voulais juste vrifier la partie .center(largeurLigne), c'est pourquoi j'ailaiss des espaces avant les chaines. Je pense que cela fait plus joli ainsi. Lesprogrammeurs ont souvent des impressions mauvaises quant ce qui peut tre joli dansun programme et le dnigrent. Plus vous programmerez, plus vous vous crerez un style).

    En parlant de paresseux, la paresse n'est pas toujours une mauvaise chose enprogrammation. Par exemple, savez-vous pourquoi j'ai stock la largeur du pome dans lavariable largeurLigne ? C'est afin que dans le cas o je reprenne plus tard le pomeet le fasse plus large, je n'ai plus que la premire ligne du programme changer et nonchaque ligne centrer. Avec un pome trs long, cela me fait gagner du temps. On peutdire que la paresse est une vertu en programmation.

    Bien, au sujet du centrage... vous avez certainement observ que ce n'est pas aussi jolique ce que vous donne un traitement de texte. Si vous voulez rellement perfectionner lecentrage (et peut-tre la fonte), alors vous devez tout simplement utiliser un traitement detexte ! Ruby est un outil magnifique, mais aucun outil n'est le bon outil pour tous les

    travaux.

    Deux autres mthodes de formatage de chane sont ljust et rjust, qui signifientrespectivement left justify (justification gauche) et right justify (justification droite). Ellessont similaires center, sauf qu'elles remplissent la chane d'espaces sur la droite pourla premire et sur la gauche pour la deuxime. Voyons un peu les trois en action :

    largeurLigne = 40str = '--> texte texte

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    25/79

    --> texte texte texte texte texte

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    26/79

    puts 5**2puts 5**0.5puts 7/3puts 7%3puts 365%7

    252.23606797749979211

    La dernire ligne nous confirme qu'une anne non bissextile a un certain nombre desemaines plus un jour. Ainsi si votre anniversaire tombe un mardi cette anne, on vous lesouhaitera un mercredi l'anne prochaine. Vous pouvez aussi utiliser des rels avec lamthode modulo. La fonction modulo est gnralise de la seule faon sense...mais jevous laisse vous amuser avec a.

    Il reste encore une mthode avant d'attaquer les nombres alatoires : abs. Elle renvoietout simplement la valeur absolue d'un nombre :

    puts (5-2).absputs (2-5).abs

    33

    Nombres alatoiresRuby nous arrive avec un trs joli gnrateur de nombre alatoire. La mthode pourobtenir un nombre au hasard est rand (de random : hasard). Si vous appelez rand telquel, vous obtiendrez un rel suprieur ou gal 0.0 et infrieur 1.0. Si vous passez rand un entier (5 par exemple) en paramtre, il vous renverra un entier suprieur ou gal 0 et strictement infrieur 5. (soit cinq nombres possibles de 0 4).

    Voyons rand en action. (Si vous recopiez cet exemple et l'excutez, le rsultat obtenuchangera chaque fois. Vous ne doutiez pas que j'essayais moi-mme ces programmes,n'est-ce pas?)

    puts randputs randputs randputs(rand(100))puts(rand(100))puts(rand(100))puts(rand(1))puts(rand(1))puts(rand(1))puts(rand(9999999999999999999999999999999999999999999999999999999999999999999999999999999999999))

    26

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    27/79

    puts('La mto nous dit qu\'il y a '+rand(101).to_s+'% de chancequ\'il pleuve,')puts('mais il ne faut jamais couter la mto.')

    0.3193185178097340.4480529013089840.44638533401303224630006033906975456789045532345676543122335776889888La mto nous dit qu'il y a 14% de chance qu'il pleuve,mais il ne faut jamais couter la mto.

    Notez que j'ai utilis rand(101) pour obtenir des nombres de 0 100, et que rand(1)retourne toujours 0. L'incomprhension de l'intervalle de valeurs possibles en retour avecrand, est un des grands mystres que je connaisse; mme chez les programmeursprofessionnels; mme dans les produits que vous pouvez acheter dans le commerce. J'aimme eu un lecteur de CD qui en mode alatoire jouait toutes les plages sauf ladernire...(je me demande ce que a aurait donn si j'avais introduit un CD avec uneseule plage ?)

    Parfois vous pouvez avoir besoin que rand retourne les mmes nombres alatoires dansla mme squence lors de deux excutions diffrentes de votre programme. (Parexemple, lorsque j'utilise des nombres alatoires pour crer un monde alatoire dans un

    jeu informatique. Si je trouve un monde qui me plait beaucoup, peut-tre souhaiterai-je yretourner, ou l'envoyer un ami.) Pour obtenir ceci, vous devrez semer une graine("seed"en anglais), ce que vous ferez avec srand. Comme ceci:

    srand 1776puts(rand(100))puts(rand(100))puts(rand(100))puts(rand(100))puts(rand(100))puts ''

    srand 1776puts(rand(100))puts(rand(100))puts(rand(100))puts(rand(100))puts(rand(100))

    149508423

    14

    27

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    28/79

    9508423

    La mme chose se produira chaque fois que vous smerez avec le mme nombre. Sivous voulez obtenir de nouveau des nombres diffrents (comme si vous n'aviez jamaisutilis srand), il suffira d'appeler srand 0. Cela smera avec un nombre trange,utilisant (parmi d'autres choses) l'horloge de votre ordinateur, et ceci jusqu' lamilliseconde.

    L'objet Math

    Regardons finalement l'objet Math. Nous pouvons tout aussi bien y plonger d'un coup :

    puts (Math::PI)puts (Math::E)puts (Math.cos(Math::PI/3))puts (Math.tan(Math::PI/4))puts (Math.log(Math::E**2))puts ((1 + Math.sqrt(5))/2)

    3.141592653589792.718281828459050.512.0

    1.61803398874989

    La premire chose que vous avez remarque est certainement la notation ::. Expliquerl'oprateur de champ (scope operator) (qui est ce qu'il est) est vraiment en dehors du,euh... champ de ce tutoriel. Bon, plus de jeux de mots. Je le jure. Il suffit de le dire, vouspouvez utiliserMath::PI pour ce que vous pensez qu'il est : la valeur de PI.

    Comme vous pouvez le voir, Math a tout ce que vous attendez d'un calculateurscientifique dcent. Et comme toujours, les rels sont rellement proches des bonnesrponses.

    28

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    29/79

    6.Contrle de flux

    Ahhh, le contrle de flux. C'est l que les Athniens s'atteignirent. Un titre mystrieux pourdire simplement que lorsque lon programme il arrive un moment o il va falloir faire unechose ou une autre, aller un endroit ou un autre, bref bifurquer. Quoique ce chapitresoit plus court et plus simple que celui des mthodes, il nous ouvrira un monde plein depossibilits pour la programmation. Aprs ce chapitre, nous serons vraiment capablesd'crire des programmes interactifs; dans le pass nous avons construit des programmesqui disaient diffrentes choses en fonction de vos entres au clavier, mais aprs cechapitre ils feront vraiment d'autres choses. Mais avant d'en arriver l, nous devons trecapables de comparer des objets dans nos programmes. Nous devons...

    Mthodes de comparaison

    Fonons tte baisse dans cette partie afin d'en arriver la prochaine section, les

    branchements, o tout le meilleur va arriver.Bien, pour voir si un objet est plus grand ou plus petit qu'un autre, nous utilisons lesmthodes > et < comme ceci :

    puts 1 > 2puts 1 < 2

    falsetrue

    false signifiant "faux" et true "vrai".

    Pas de problme. De la mme faon nous pouvons dire si un objet est plus grand que ougal un autre (ou infrieur ou gal) avec les mthodes >= et = 5puts 5

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    30/79

    puts 'chat' < 'chien'

    true

    Il y a cependant un petit problme : les ordinateurs considrent que les majuscules

    prcdent les minuscules dans les fontes qu'ils utilisent. (Ceci parce que dans les fontes,l'alphabet est en double et les majuscules sont places avant). Cela signifie que Zoovient avant abat, et que si vous voulez qu'un mot figure en premier dans undictionnaire, il ne faut pas oublier d'appliquer downcase (ou upcase ou capitalize)sur les deux mots avant de les comparer.

    Une dernire remarque avant les branchements : les mthodes de comparaison ne nousdonnent pas les chaines 'true' et 'false'; elles nous renvoient les objets spciaux trueet false. (Bien entendu, true.to_s nous donne 'true', c'est pour a que puts affiche'true'.) true et false sont le plus souvent utiliss dans...

    les branchements

    Les branchements sont un concept simple, mais nanmoins magnifique. En fait, il est sisimple que je parie que je n'ai jamais eu l'expliquer quiconque; je vais juste vous lemontrer :

    puts 'Bonjour, quel est votre prnom ?'nom = gets.chompputs 'Bonjour, ' + nom + '.'if nom == 'Christian'puts 'Quel joli prnom vous avez !'

    end

    Bonjour, quel est votre prnom ?ChristianBonjour, Christian.Quel joli prnom vous avez !

    Mais si nous rpondons par un prnom diffrent...

    Bonjour, quel est votre prnom ?Gaston

    Bonjour, Gaston.Le branchement c'est a. Si ce qui suit le si (if) est vrai (true), le code situ entre le si(if) et la fin (end) est excut. Si ce qui suit le si (if) est faux (false), rien n'estexcut. Clair et net !

    J'ai indent (mis en retrait du bord) le code entre le if et le end uniquement parce que jepense qu'il est plus facile ainsi de reprer le branchement. La plupart des programmeursfont comme cela, quelque soit leur langage de programmation. Cela ne parat pas tred'une aide formidable dans cet exemple, mais quand les choses se compliquent, a faitune grande diffrence.

    30

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    31/79

    Souvent, nous aimerions un programme qui fasse quelque chose si une expression estvraie, et une autre si elle est fausse. C'est pour cela que else (sinon) existe:

    puts 'Je suis une voyante. Donnez-moi votre prnom :'nom = gets.chomp

    if nom == 'Christian'puts 'Je vois de grandes choses dans votre avenir.'

    elseputs 'Votre futur est... Oh, bon sang ! Regardez l'heure qu\'il

    est !'puts 'je n\'ai plus le temps... dsole !'

    end

    Je suis une voyante. Donnez-moi votre prnom :ChristianJe vois de grandes choses dans votre avenir.

    Maintenant essayons un autre prnom...

    Je suis une voyante. Donnez-moi votre prnom :GastonVotre futur est... Oh, bon sang ! Regardez l'heure qu'il est !je n'ai plus le temps... dsole !

    Le branchement est comme une bifurcation dans le code : nous prenons un chemin pourles gens qui se prnomment Christian, et un autre dans le cas contraire.Et tout comme les branches d'un arbre, vous pouvez avoir des branches qui ont elles-

    mmes d'autres branches.(C'est ce que l'on appelle, dans le jargon des programmeurs,des "if" imbriqus.)

    puts 'Bonjour, et bienvenue au club.'puts 'Mon nom est Mademoiselle Longbec. Et votre nom est...'nom = gets.chomp

    if nom ==nom.capitalizeputs 'Je vous en prie, asseyez-vous, ' + nom + '.'

    elseputs nom + '? Vous voulez dire ' + nom.capitalize + ', non ?'puts 'On ne vous a donc jamais appris crire correctement

    votre nom ?'bis = gets.chomp

    if bis.downcase == 'oui'puts 'Hmmm... bon asseyez-vous !'

    elseputs 'Dehors !!'

    endend

    31

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    32/79

    Bonjour, et bienvenue au club.Mon nom est Mademoiselle Longbec. Et votre nom est...christianchristian? Vous voulez dire Christian, non ?On ne vous a donc jamais appris crire correctement votre nom?

    ouiHmmm... bon asseyez-vous !

    Mieux, je "capitalize" mon prnom...

    Bonjour, et bienvenue au club.Mon nom est Mademoiselle Longbec. Et votre nom est...ChristianJe vous en prie, asseyez-vous, Christian.

    Parfois il peut y avoir confusion et on ne sait plus o conduisent lesif, else et end.Ce que je fais, c'est que je commence par les crire et je comble ensuite avec le code.Ainsi le programme ci-dessus ressemble ceci au dbut de sa conception :

    puts 'Bonjour, et bienvenue au club.'puts 'Mon nom est Mademoiselle Longbec. Et votre nom est...'nom = gets.chomp

    if nom ==nom.capitalizeelseend

    Ensuite je remplis avec des commentaires, que la machine ignorera :

    puts 'Bonjour, et bienvenue au club.'puts 'Mon nom est Mademoiselle Longbec. Et votre nom est...'nom = gets.chomp

    if nom ==nom.capitalize# l elle est civile.

    else# l elle est enrage.

    end

    Tout ce qui suit "#" est considr comme un commentaire (sauf bien sr si vous tes dansune chane de caractres). Aprs ceci, je remplace les commentaires par du code actif.Certains laissent ces commentaires; personnellement je pense qu'une bonne criture ducode parle d'elle-mme. Autrefois je faisais plus de commentaires, mais plus j'utilise Rubymoins j'en fais. Je trouve cela plus troublant qu'autre chose. Mais c'est une affaire de got;vous trouverez petit petit votre style. Ma prochaine tape ressemblait cel :

    puts 'Bonjour, et bienvenue au club.'puts 'Mon nom est Mademoiselle Longbec. Et votre nom est...'

    nom = gets.chomp

    32

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    33/79

    if nom ==nom.capitalizeputs 'Je vous en prie, asseyez-vous, ' + nom + '.'

    elseputs nom + '? Vous voulez dire ' + nom.capitalize + ', non ?'puts 'On ne vous a donc jamais appris crire correctement

    votre nom ?'bis = gets.chompif bis.downcase == 'oui'

    else

    endend

    De nouveau j'ai cris les if, else, end en mme temps. C'est vraiment trs utile pour savoir

    o "je suis" dans le code. Cela facilite le travail parce que je peux me focaliser sur unepetite partie, comme remplir le code entre le ifet le else. Un autre avantage de procderainsi est que l'ordinateur comprend le programme chaque tape. Chaque versioninacheve du programme ci-dessus fonctionne sans problme. Ce ne sont pas desprogrammes termins mais ce sont des programmes qui cependant fonctionnent. Ainsi jepeux les tester au fur et mesure de leur conception et visualiser plus facilement le travailachev et celui qui reste accomplir. Une fois tous les tests accomplis, je sais que j'aitermin !

    Ces trucs vous aideront crire des programmes possdant des branchements, mais ilsvous aideront aussi avec l' autre principal type de contrle de flux :

    Les boucles

    Souvent vous dsirerez que votre ordinateur fasse la mme chose encore et encore.Aprs tout ne dit-on pas que c'est dans les tches rptitives que ces machines excellent?

    Lorsque vous dites votre ordinateur de rpter quelque chose, vous devez aussi penser lui dire quand s'arrter.Les ordinateurs ne se lassent jamais, aussi si vous omettez deleur dire de s'arrter, ils ne le feront pas. Nous nous assurerons que cela n'arrivera pas,en disant l'ordinateur de rpter une partie du programme tant (while) qu'une conditionest vraie (true). Cela ressemble beaucoup au fonctionnement de if:

    commande = ''

    while commande != 'Ciao'puts commandecommande = gets.chomp

    end

    puts 'Au revoir, bientt !'

    Coucou ?

    Coucou ?Oh !

    33

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    34/79

    Oh !CiaoAu revoir, bientt !

    Et voil pour une boucle. (Vous avez not la ligne blanche au dbut des rponses; c'est

    cause du premierputs, avant le premiergets. Comment modifieriez-vous le programmepour supprimer cette ligne blanche ? Essayez! le programme doit fonctionner exactementcomme avant, except la premire ligne.)

    Les boucles vous permettent de faire plein de choses intressantes, comme je suispersuad que vous allez en imaginer. Cependant elles peuvent crer des problmes sivous vous trompez. Que faire si votre ordinateur entre dans une boucle infinie ? Si vouspensez que vous tes dans ce cas, il suffit d'appuyer sur les touches "Ctrl" et "C".

    Avant que de s'amuser avec les boucles, apprenons donc quelques petits trucs pour nousfaciliter le travail.

    Un petit peu de logique

    Regardons un peu notre premier programme sur les branchements. Supposons que mafemme rentre la maison, voit le programme, l'essaye, et qu'il ne lui dise pas qu'elle a unjoli prnom ? Je ne voudrais pas heurter sa sensibilit (ni dormir sur le canap !), aussi jele recris comme ceci :

    puts 'Bonjour, quel est votre prnom ?'nom = gets.chomp

    puts 'Bonjour, ' + nom + '.'if nom == 'Christian'puts 'Quel joli prnom vous avez !'

    else if nom =='Cathy'

    puts 'Quel joli prnom vous avez !' endend

    Bonjour, quel est votre prnom ?CathyBonjour, Cathy.

    Quel joli prnom vous avez !

    Bon, a marche... mais ce n'est pas encore un joli programme. Pourquoi non ? parce quela meilleure rgle que j'ai apprise en programmant a t la rgle PDR : Pas DeRptitions. Je devrais certainement crire un petit livre pour expliquer pourquoi c'est unebonne rgle. Dans notre cas, nous rptons la ligne puts 'Quel joli prnom vousavez !'. Pourquoi est-ce si important ? Premirement, que se passe-t-il si je me trompeen recopiant la ligne ? deuximement si je veux changer "joli" par "magnifique" dans lesdeux lignes ? Je suis paresseux si vous vous souvenez ? De faon simple, si je veux quemon programme rponde la mme chose quand on lui dit 'Christian' ou 'Cathy', alors il doitrellement faire la mme chose :

    34

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    35/79

    puts 'Bonjour, quel est votre prnom ?'nom = gets.chompputs 'Bonjour, ' + nom + '.'if (nom == 'Christian' or nom == 'Cathy')puts 'Quel joli prnom vous avez !'

    endBonjour, quel est votre prnom ?CathyBonjour, Cathy.Quel joli prnom vous avez !

    C'est mieux. En fait pour obtenir ce rsultat j'ai utilis or (ou). Les autres oprateurslogiques sont and (et) et not (pas). Il vaut mieux utiliser des parenthses lorqu'on travailleavec eux. Regardons un peu leur fonctionnement :

    jeSuisChristian = truejeSuisViolet = falsejaimeManger = truejeSuisEnPierre = false

    puts (jeSuisChristian and jaimeManger)puts (jaimeManger and jeSuisEnPierre)puts (jeSuisViolet and jaimeManger)puts (jeSuisViolet and jeSuisEnPierre)putsputs (jeSuisChristian or jaimeManger)puts (jaimeManger or jeSuisEnPierre)

    puts (jeSuisViolet or jaimeManger)puts (jeSuisViolet or jeSuisEnPierre)putsputs (not jeSuisViolet)puts (not jeSuisChristian)

    truefalsefalsefalse

    true

    truetruefalse

    truefalse

    Le seul qui puisse vous jouer des tours est "or". En franais, nous utilisons souvent "ou"en pensant "un ou l'autre, mais pas les deux". Par exemple, votre maman peut dire "Audessert, il y a du gateau ou du flan." Elle n'envisage pas une seconde que vous puissiezvouloir des deux ! Un ordinateur au contraire, utilise "ou" en pensant "un ou l'autre, ou les

    deux." (Une autre faon de dire serait : "au moins un des deux est vrai") C'est pour celaque les ordinateurs sont plus amusants que les mamans !

    35

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    36/79

    Quelques petites choses essayer

    Ecrivez un programme Mamie est sourde. Quoique vous disiez Mamie

    (quoique vous tapiez plutt), elle vous rpond par "Hein ?! Parle plus fort !",jusqu' ce que vous criiez (tapez en majuscule). Si vous criez, elle peut vousentendre (ou du moins c'est ce qu'elle pense) et vous rpond, "non, pas depuis1938 !" Pour rendre votre programme plus raliste, Mamie doit rpondre par unedate diffrente chaque fois; cela peut tre alatoirement entre 1930 et 1950.(Cette partie est optionnelle, et vous serez plus l'aise aprs avoir lu la sectionde Ruby traitant du gnrateur de nombres alatoires la fin du chapitre sur lesmthodes.) Vous ne pouvez pas cesser de rpondre Mamie jusqu' ce quevous entriez Ciao.

    Remarque : n'oubliez pas chomp ! 'Ciao' avec un "Enter" n'est pas le mme quesans!

    Remarque 2: Essayez d'imaginer quelle partie de votre programme doit se rpterencore et encore. Tout cela doit tre dans votre boucle while.

    Amliorez votre programme sur Mamie qui est sourde : Que faire si Mamie neveut pas que vous la quittiez ? Quand vous criez "Ciao", elle prtend ne pasvous entendre. Changez votre prcdent programme de telle sorte que vousdevez crier "Ciao" trois fois sur la mme ligne pour qu'elle vous entende. Testezvotre programme : si vous criez trois fois "Ciao", mais pas sur la mme ligne,vous devrez continuer rpondre Mamie.

    Les annes bissextiles. Ecrivez un programme qui vous demande une anne dedpart et une anne de fin, puis affichez toutes les annes bissextiles entre cesdeux limites (en les incluant si tel est le cas). Les annes bissextiles sont desannes divisibles par quatre (comme 1984 et 2004). Cependant, les annesdivisibles par 100 ne sont pas bissextiles (comme 1800 et 1900) sauf si ellessont divisibles par 400 (comme 1600 et 2000).(Oui cela prte une jolieconfusion, mais pas autant que d'avoir juillet au milieu de l'hiver, ce qui peutventuellement arriver.)

    Quand vous aurez termin tout cela, prenez donc une pause ! Vous avez dj appris pasmal de choses. Flicitations ! Ralisez-vous le nombre de choses que vous pouvezdemander un ordinateur maintenant ? Encore quelques chapitres et vous serez capable

    de programmer n'importe quoi. Srieusement ! Regardez tout ce que vous pouvez fairedepuis que vous connaissez les boucles et branchements.

    Nous allons maintenant nous attaquer une nouvelle sorte d'objet qui garde une trace,sous forme de liste, des autres objets : les tableaux.

    36

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    37/79

    7. Tableaux et itrateurs

    Ecrivons un programme qui nous demande d'entrer autant de mots que nous voulons (unmot par ligne, jusqu' ce que nous tapions la touche "Enter" sur une ligne vide), et quinous renvoie ces mots par ordre alphabtique. D'accord ?

    Bon... en premier -heu... Hummm... Bon, nous devons... Hummm...

    Vous savez, je ne pense pas que nous puissions faire cela. Nous avons besoin d'unmoyen de stocker un certain nombre de mots, et d'un autre pour en garder la trace, detelle sorte qu'il n'y ait pas de mlange avec les autres variables. Nous avons besoin de lesgarder dans une sorte de liste. Nous avons besoin de tableaux.

    Un tableau est tout simplement une liste dans votre ordinateur. Chaque lment de la listeagit comme une variable : vous pouvez voir quelle sorte d'objet pointe sur un lment detableau, et nous pouvons le faire pointer vers un objet diffrent. Jetons un coup d'oeil surquelques tableaux :

    [][5]['Bonjour', 'Adieu']

    parfum = 'Vanille' # ceci n'est pas un tableau, bien sr...[89.9, parfum, [true, false]] # mais ceci, oui.

    Pour commencer nous avons un tableau vide, puis un tableau contenant un simple entier,puis un tableau avec deux chaines de caractres. Ensuite vient un assignement; puis untableau contenant trois objets, le dernier tant lui-mme un tableau [true, false].Souvenez-vous, les variables ne sont pas des objets, notre dernier tableau pointe doncrellement sur un rel, une chane, et un tableau. Mme si nous faisons pointerparfumsur quelque chose d'autre, cela ne change pas le tableau.

    Pour nous aider trouver un objet particulier dans un tableau, chaque lment correspond un index. Les programmeurs (et, accidentellement la plupart des mathmaticiens) com-mencent compter partir de zro, ainsi le premier lment dans le tableau est l'lmentzro. Ce qui suit nous montre comment faire rfrence des objets dans un tableau :

    noms = ['Ada', 'Belle', 'Christiane']

    puts nomsputs noms[0]puts noms[1]puts noms[2]puts noms[3] # ceci est hors indice.

    AdaBelleChristiane

    AdaBelle

    37

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    38/79

    Christianenil

    Bon, nous voyons que puts noms affiche chaque nom du tableau noms. Puis nous util-isons puts noms[0] pour afficher le "premier" nom du tableau, et puts noms[1] pour

    le second... Je suis sr que cela vous parait confus, mais vous devez l'utiliser ainsi. Vousn'avez qu' rellement commencer compter en pensant que pour compter on dbute zro, et arrter d'utiliser des mots tels que "premier" et "second". Si vous jouez aux cours-es, ne parlez plus de la "premire"; parlez de la course zro (et dans votre tte pensezcourse[0]). Vous avez cinq doigts votre main droite et ils sont numrots 0, 1, 2, 3 et 4.Vous saurez que vous y tes arriv quand vous direz "le quatrime lment du tableau", etque vous penserez rellement monTableau[4]. Cela apparatra vraisemblablement lorsquevous parlerez aussi du "zroime". Si, si, le mot existe; demandez donc un program-meur ou un mathmaticien.

    Pour finir, nous avons essay puts nom[3], juste pour voir ce que cela donnait. Vous

    attendiez une erreur, n'est-ce pas ? Parfois vous posez une question, votre question n'apas de sens (du moins pour votre ordinateur); c'est l que vous obtenez une erreur. Par-fois, cependant, vous pouvez poser une question dont la rponse est rien. Quel est letroisime lment du tableau ? rien. Qu'est-ce que noms[3] ? nil : c'est la faon de Ru-by de dire "rien". nil est un objet spcial qui signifie "plus d'autre objet".

    Si toute cette jolie numrotation dlments de tableaux vous rend perplexe , ne vous ef-frayez pas ! Souvent nous pouvons lviter compltement en utilisant diverses mthodesdes tableaux, comme celle-ci :

    La mthode eacheach nous permet de faire quelque chose (tout ce que nous voulons) each (chaque) ob-jet du tableau. Ainsi si nous souhaitons dire quelque chose d'agrable pour chaque lan-gage du tableau ci-dessous, nous ferons comme ceci :

    langages = ['Anglais', 'Allemand', 'Ruby']

    langages.each do |langue|puts 'J\' aime parler en ' + langue + ' !'puts 'Pas vous ?'

    end

    puts 'Et tant pis pour le C++ !'puts '...'

    J' aime parler en Anglais !Pas vous ?J' aime parler en Allemand !Pas vous ?J' aime parler en Ruby !Pas vous ?Et tant pis pour le C++ !

    ...

    38

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    39/79

    Que se passe-t-il au juste ? Nous sommes capables d'aller d'objet en objet dans letableau sans utiliser aucun nombre, ce qui est parfait.Traduit en franais, le programme ci-dessus quivaut : pour chaque (each) objet danslangages, pointez la variable langue vers l'objet et puis faire (do) tout ce que je vousdemande, jusqu' ce que vous arriviez la fin (end). (Juste une remarque; comme vous le

    savez C++ est un autre langage de programmation. Nettement plus difficile apprendreque Ruby. En gnral un programme en C++ est plus long quun programme en Rubypour faire la mme chose.)En votre for intrieur vous devez vous dire, "C'est la mme chose que les boucles quenous avons apprises il y a peu de temps." Oui, a y ressemble. Une diffrence importanteest que la mthode each est uniquement cela : une mthode. while et end (ou mieuxdo, if, else et tous les autres mots en bleu) ne sont pas des mthodes. Ce sont unepartie fondamentale du langage Ruby, tout comme = et les parenthses.

    Mais pas each; each est seulement une mthode de tableaux. Les mthodes qui agis-sent comme les boucles sont souvent appelles des itrateurs.

    Une chose noter au sujet des itrateurs, c'est qu'ils sont toujours suivis de do...end.while et if n'ont jamais un do ct d'eux; nous n'utilisons do qu'avec les itrateurs.

    Voici un ingnieux petit itrateur, mais il ne s'agit pas d'une mthode de tableaux... c'estune mthode d'entiers !

    3.times doputs 'Hip, Hip, Hip, Hourra !'

    end

    Hip, Hip, Hip, Hourra !Hip, Hip, Hip, Hourra !Hip, Hip, Hip, Hourra !

    Quelques petites choses essayer

    Ecrivez le programme dont nous parlions au tout dbut de ce chapitre.Remarque : il existe une trs apprciable mthode de tableaux qui vous donnera une ver-sion trie d'un tableau : sort. Utilisez-la !

    Essayez d'crire le programme ci-dessus sans utiliser la mthode sort. La plu-part du temps la programmation consiste rsoudre des problmes, aussi met-tez en pratique tout ce que vous pouvez !

    D'autres mthodes de tableaux

    Nous venons d'apprendre each et sort,mais il existe de nombreuses autres mthodesde tableaux... la plupart d'entre elles sont des mthodes de chanes! En fait, certaines(comme length, reverse, + et *) fonctionnent comme pour des chanes, part qu'elles

    agissent sur les lments du tableau plutt que sur les lettres d'une chane. D'autre,comme last et join, sont spcifiques aux tableaux. D'autres encore, comme push et

    39

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    40/79

    pop, changent mme le tableau. Et, exactement comme pour les mthodes de chanes,vous n'avez pas vous souvenir de toutes ces mthodes, il vous suffit de savoir o retrou-ver leur description (ici par exemple).

    aliments = ['artichaut', 'brioche', 'caramel']

    puts alimentsputsputs aliments.to_sputsputs aliments.join(', ')putsputs aliments.join(' :) ') + ' 8)'

    200.times doputs []

    endartichautbriochecaramel

    artichautbriochecaramel

    artichaut, brioche, caramel

    artichaut :) brioche :) caramel 8)

    Comme vous pouvez le voir, puts traite les tableaux diffremment des autres objets :puts est appel pour chaque lment du tableau. C'est pour cette raison que putser untableau vide 200 fois ne fait rien; le tableau pointant sur rien, il ny a donc rien pourputs.(Ne rien faire 200 fois est comme ne rien faire du tout). Essayez de "putser" un tableaucontenant d'autres tableaux; est-ce que le rsultat est conforme votre attente ?

    Avez-vous remarqu que je laisse des chanes vides lorsque je veux afficher une ligneblanche ? c'est la mme chose.

    Jetons maintenant un coup d'oeil push ,pop et last. Les mthodes push et pop sonten quelque sorte opposes comme + et -, push ajoute un objet la fin de votre tableau, et

    pop enlve le dernier objet du tableau en affichant ce qu'il tait. last est similaire popen ce sens qu'il indique ce qu'il y a la fin du tableau, mais sans rien supprimer. Rp-tons-le, push et pop modifient rellement le tableau:

    favoris =[]favoris.push '2001 l\'Odysse de l\'espace'favoris.push 'Docteur Folamour'

    puts favoris[0]puts favoris.lastputs favoris.length

    puts favoris.popputs favoris

    40

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    41/79

    puts favoris.length

    2001 l'Odysse de l'espaceDocteur Folamour2Docteur Folamour2001 l'Odysse de l'espace1

    Quelques petites choses essayer

    Rcrivez votre table des matires (du chapitre sur les mthodes). Dbutez leprogramme par un tableau contenant toutes les informations de la table desmatires (noms des chapitres, numros de pages, etc...). Puis extrayez les in-formations dans une magnifique Table des Matires formate.

    Puisque nous avons appris un certain nombre de mthodes, il est temps prsentd'apprendre fabriquer les ntres.

    41

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    42/79

    8. Ecrire vos propres mthodes

    Comme nous l'avons vu, les boucles et les itrateurs nous permettent de faire la mmechose (excuter le mme code) encore et encore. Cependant, parfois nous voudrions faireune chose un certain nombre de fois mais partir d'endroits diffrents du programme. Parexemple, imaginons que nous crivons un questionnaire pour un tudiant en psychologie.Ce sont d'ailleurs des tudiants en psychologie que je connais qui m'ont donn le ques-tionnaire qui ressemblait peu prs ceci :

    puts 'Bonjour, et merci de prendre le temps'puts 'de m\'aider dans cette exprience. Mon exprience'puts 'a trait la perception par les gens de la 'puts 'nourriture Mexicaine. Pensez uniquement la'puts 'nourriture Mexicaine et essayez de rpondre'puts 'honntement toutes les questions, soit par'puts 'un "oui" soit par un "non". Mon exprience n\'a'puts 'absolument rien voir avec le pipi au lit.'puts

    # Nous posons ces questions, mais nous en ignorons les rponses.

    bonneReponse = falsewhile (not bonneReponse)puts 'Aimez-vous manger des tacos?'reponse = gets.chomp.downcase

    if (reponse == 'oui' or reponse == 'non')

    bonneReponse = true else

    puts 'S\'il vous plait, rpondez par "oui" ou par "non".' endend

    bonneReponse = falsewhile (not bonneReponse)puts 'Aimez-vous les burritos?'reponse = gets.chomp.downcase

    if (reponse == 'oui' or reponse == 'non')bonneReponse = true

    elseputs 'S\'il vous plait, rpondez par "oui" ou par "non".'

    endend

    # C'est cette rponse que nous devons prter attention.

    bonneReponse = falsewhile (not bonneReponse)puts 'Faites-vous pipi au lit?'reponse = gets.chomp.downcase

    if (reponse == 'oui' or reponse == 'non')bonneReponse = true

    42

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    43/79

    if reponse == 'oui'pipi = true

    elsepipi = false

    end

    elseputs 'S\'il vous plait, rpondez par "oui" ou par "non".' endend

    bonneReponse = falsewhile (not bonneReponse)puts 'Aimez-vous les chimichangas?'reponse = gets.chomp.downcase

    if (reponse == 'oui' or reponse == 'non')bonneReponse = true

    elseputs 'S\'il vous plait, rpondez par "oui" ou par "non".'

    endend

    puts 'Plus que quelques questions...'

    bonneReponse = falsewhile (not bonneReponse)puts 'Aimez-vous les sopapillas?'reponse = gets.chomp.downcase

    if (reponse == 'oui' or reponse == 'non')

    bonneReponse = true elseputs 'S\'il vous plait, rpondez par "oui" ou par "non".'

    endend

    # Posez d'autres questions sur les plats mexicains si vousvoulez.

    putsputs 'Compte-rendu:'puts 'Merci d\'avoir pris le temps de m\'aider'puts 'dans cette exprience. En fait, cette exprience'puts 'n\'a rien voir avec la nourriture Mexicaine.'puts 'C\'est une tude sur le pipi au lit. La nourriture'puts 'Mexicaine n\'tait l que pour dtourner l\'attention'puts 'en esprant que vous rpondiez honntement. Merci encore.'putsputs pipi

    Bonjour, et merci de prendre le tempsde m'aider dans cette exprience. Mon expriencea trait la perception par les gens de lanourriture Mexicaine. Pensez uniquement lanourriture Mexicaine et essayez de rpondrehonntement toutes les questions, soit par

    43

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    44/79

    un "oui" soit par un "non". Mon exprience n'aabsolument rien voir avec le pipi au lit.

    Aimez-vous manger des tacos?oui

    Aimez-vous les burritos?ouiFaites-vous pipi au lit?Plat-il?S'il vous plait, rpondez par "oui" ou par "non".Faites-vous pipi au lit?NONAimez-vous les chimichangas?ouiPlus que quelques questions...Aimez-vous les sopapillas?oui

    Compte-rendu:Merci d'avoir pris le temps de m'aiderdans cette exprience. En fait, cette expriencen'a rien voir avec la nourriture Mexicaine.C'est une tude sur le pipi au lit. La nourritureMexicaine n'tait l que pour dtourner l'attentionen esprant que vous rpondiez honntement. Merci encore.

    false

    Ce fut un long programme, avec son lot de rptitions. (Toutes les sections de code con-cernant les questions sur la nourriture Mexicaine taient identiques, et seule la questionsur le pipi au lit diffrait sensiblement.) Les rptitions sont une mauvaise chose. Seule-ment nous ne pouvons tout mettre dans une grande boucle ou des itrateurs, parce queparfois nous avons des choses faire entre deux questions. Dans de telles situations, ilvaut mieux crire une mthode. Et voici comment :

    def meuglerputs 'Meuhhh...'

    end

    Euh... notre programme ne meugle pas. Pourquoi ? Parce que nous ne lui avons pasdit de le faire. Nous lui avons dit comment meugler, mais pas de le faire. Essayons encoreune fois :

    def meuglerputs 'Meuhhh...'

    end

    meuglermeuglerputs 'quack ! quack !meugler

    44

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    45/79

    meugler

    Meuhhh...Meuhhh...quack ! quack !Meuhhh...Meuhhh...

    Ah ! C'est mieux. (Juste au cas o vous ne parleriez pas anglais, c'est un canard anglaisau milieu du programme. Dans les pays anglo-saxons les canards font " quack ! quack !".)

    Nous dfinissons la mthode meugler. (Les noms de mthodes, comme ceux des vari-ables, dbutent par une minuscule. Il y a quelques exceptions, comme + ou ==). Mais lesmthodes ne sont-elles pas toujours associes des objets ? La rponse est oui, et dansce cas (comme avec puts et gets), la mthode est simplement lie l'objet reprsentantle programme tout entier. Dans le prochain chapitre nous verrons comment ajouter des

    mthodes aux autres objets. Mais pour le moment :

    Paramtres de mthodes

    Vous avez certainement not que certaines mthodes (comme gets, to_s, reverse),s'appellent partir d'un objet. D'autres mthodes cependant, (comme +, -, puts...) nces-sitent un paramtre pour indiquer l'objet comment excuter la mthode. Par exemplevous ne dites pas simplement 5+, n'est-ce pas ? Cela voudrait dire que vous appellez 5pour ajouter, mais ajouter quoi ?

    Pour ajouter un paramtre la mthode meugler (pour indiquer le nombre de meugle-ments par exemple), nous ferons comme ceci :

    def meugler nombreMeuhputs 'Meuhhh...'* nombreMeuh

    end

    meugler 3puts 'coin-coin'meugler # Ici l'oubli du paramtre va dclencher une erreur.

    Meuhhh...Meuhhh...Meuhhh...coin-coinp45.rb:7 :in 'meugler':wrong # of arguments (0 for 1)(ArgumentError)

    from p45.rb:7

    nombreMeuh est une variable qui pointe sur le paramtre pass la mthode. Je lerpte, parce que c'est un peu confus : nombreMeuh est une variable qui pointe sur leparamtre. Ainsi si je tape meugler 3, le paramtre est 3, et la variable nombreMeuhpointe sur3.

    45

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    46/79

    Comme vous le voyez un paramtre est maintenant requis. Aprs tout, par quoi 'Meuh-hh...' est-il suppos tre multipli si on ne donne pas un paramtre? Votre "pvre" ordina-teur ne le sait pas.

    Si les objets sont en Ruby comme des noms en franais, et les mthodes comme des

    verbes, alors vous pouvez imaginer les paramtres comme des adverbes (comme avecmeugler, o le paramtre nous disait comment faire meugler) ou parfois comme des com-plments dobjets directs (comme avec puts, o le paramtre est ce qu'il faut putser).

    Variables locales

    Dans le programme suivant il y a deux variables :

    def doubler nombredeuxFois = nombre * 2puts nombre.to_s + ' doubl fait ' + deuxFois.to_s

    end

    doubler 44

    44 doubl fait 88

    Les variables sont nombre et deuxFois. Elles sont toutes deux l'intrieur de la mth-ode doubler. Ce sont (comme celles que nous avons dj vues) des variables locales.Cela signifie qu'elles vivent l'intrieur de la mthode, et ne peuvent en sortir. Si vous es-sayez, vous obtiendrez une erreur :

    def doubler nombredeuxFois = nombre * 2puts nombre.to_s + ' doubl fait ' + deuxFois.to_s

    end

    doubler 44puts deuxFois.to_s

    44 doubl fait 88p46.rb:7: undefined local variable or method `deuxFois' for # (NameError)

    Variable locale indfinie...En fait nous avons dfini cette variable, mais elle n'est pas locale l'endroit o nous voulons l'utiliser. Elle est locale la mthode.

    Cela peut paratre comme un inconvnient, mais pas du tout. Puisque cela signifie quevous n'avez pas accs aux variables internes des mthodes, cela veut dire aussi que cesdernires n'ont pas accs aux vtres, et ne peuvent donc les "bousiller" :

    def petitePeste varvar = nilputs 'Ha, Ha ! : votre variable ne vaut plus rien !'

    end

    46

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    47/79

    var = 'Personne ne touche ma variable !'petitePeste varputs var

    Ha, Ha ! : votre variable ne vaut plus rien !Personne ne touche ma variable !

    Il y a en fait , dans ce petit programme, deux variables appelles var : une l'intrieur dela mthode petitePeste et l'autre externe elle. Quand nous appelons petitePestevar, nous ne faisons que passer une chane d'une var l'autre, de telle sorte que lesdeux pointent sur la mme chane. La petitePeste peut donc faire pointer sa variable lo-cale surnil, cela ne concerne pas la variable du mme nom l'extrieur. Il est tout demme dconseill de se prter ce petit jeu de noms identiques...

    Valeurs de retour

    Vous avez peut-tre not que certaines mthodes vous retournaient quelque choselorsque vous les appeliez. Par exemple gets vous renvoie une chane (celle que vousavez entre), et la mthode + dans 5 + 3 (qui est en ralit 5.+(3)) renvoie 8. Les mth-odes arithmtiques appliques aux nombres retournent des nombres,et les mthodesarithmtiques pour les chanes renvoient des chanes.

    Il est important de comprendre la diffrence qu'il y a entre les mthodes retournant unevaleur l'endroit d'o elles ont t appeles, et votre programme qui affiche des informa-tions sur l'cran, comme le fait puts. Notez que 5+3 retourne 8; il n'affiche pas 8.

    Mais que retourne donc puts ? Nous n'avons jamais fait attention cela, mais il n'est

    pas trop tard pour regarder :

    valeurRetour = puts 'Ce puts retourne : 'puts valeurRetour

    Ce puts retourne :nil

    Si la variable valeurRetour pointe surnil (2me ligne de rponse) c'est que puts aretourn nil dans la premire ligne. puts renvoie toujours une valeurnil. Toute mth-ode se doit de retourner quelque chose, mme s'il ne s'agit que de nil.

    Faites une petite pause et crivez un programme pour voir ce que retourne la mthodemeugler.

    Etes-vous surpris(e) ? Bon, voici comment a marche : la valeur retourne par une mth-ode est tout simplement la dernire ligne de la mthode. Pour vous en convaincre, rem-placez puts par l'affectation une variable interne (var1 = 'Meuhhh...'* nombre-Meuh) et rexcutez le programme. Si nous voulons que nos mthodes retournent toutesla mme chane 'caramel', il nous suffit de mettre cette chane en dernire ligne :

    def meugler nombreMeuhputs 'Meuhhh...'* nombreMeuh

    47

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    48/79

    'Caramel'end

    x = meugler 2puts x

    Meuhhh...Meuhhh...Caramel

    Bien, essayons de nouveau l'exprience de psychologie, mais laissons cette fois unemthode poser les questions pour nous. Il sera ncessaire de considrer la questioncomme un paramtre de mthode, et d'avoir comme valeur de retourtrue (vrai) si larponse "oui" et false (faux) si la rponse est "non". (Mme si la plupart du temps larponse nous est indiffrente, c'est seulement une bonne ide que de faire retourner unevaleur par nos mthodes. Et nous pourrons aussi l'utiliser pour la question sur le pipi aulit).J'ai raccourci l'introduction et le compte-rendu pour faciliter la lecture :

    def interroge questionbonneReponse = false

    while (not bonneReponse)puts questionreponse = gets.chomp.downcase

    if (reponse == 'oui' or reponse == 'non')bonneReponse = true

    if reponse == 'oui'retour = true

    elseretour =false

    end else

    puts 'S\'il vous plait, rpondez par "oui" ou par "non".' end endretour # C'est ce que la mthode retourne. (true ou false)

    end

    puts 'Bonjour, et merci de prendre le temps...'

    puts

    interroge 'Aimez-vous manger des tacos?'interroge 'Aimez-vous les burritos?'pipi = interroge 'Faites-vous pipi au lit?'interroge 'Aimez-vous les chimichangas?'interroge 'Aimez-vous les sopapillas?'interroge 'Aimez-vous les tamales?'puts 'Plus que quelques questions...'interroge 'Aimez-vous boire de l\'horchata?'interroge 'Aimez-vous les flotas?'

    puts

    48

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    49/79

    puts 'Compte-rendu:'puts 'Merci d\'avoir pris le temps de m\'aider...'putsputs pipi

    Bonjour, et merci de prendre le temps...'

    Aimez-vous manger des tacos?ouiAimez-vous les burritos?ouiFaites-vous pipi au lit?Plait-il?S'il vous plait, rpondez par "oui" ou par "non".NONAimez-vous les chimichangas?oui

    Aimez-vous les sopapillas?ouiAimez-vous les tamales?ouiPlus que quelques questions...Aimez-vous boire de l'horchata?ouiAimez-vous les flotas?oui

    Compte-rendu:Merci d'avoir pris le temps de m'aider...

    false

    Pas mal, non? Nous avons la possibilit d'ajouter des questions (et c'est maintenantfacile) et notre programme est nettement plus court! C'est une nette amlioration, un rvede programmeur paresseux.

    Encore un long exemple

    Je pense un autre exemple de mthode susceptible de nous aider. Nous l'appellerons

    nombreBelge. Elle prend un nombre en paramtre, par exemple 22, et retourne la ver-sion en toutes lettres (soit "vingt-deux"). Pour le moment cantonnons-nous aux nombresde 0 100.

    (Remarque : cette mthode utilise une nouvelle astuce en forant prmaturment unevaleur de retour l'aide du mot-cl return, et en introduisant un nouveau test debranchement : elsif (sinon si). Cela est suffisamment clair dans l'exemple qui suit)

    def nombreBelge nombre# Nous voulons seulement des nombres de 0 100.

    if nombre < 0

    return 'SVP entrez un nombre = zro ou suprieur.' end

    49

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    50/79

    if nombre > 100 return 'SVP entrez un nombre = 100 ou infrieur.' endchaineNombre = '' # C'est la chane que nous retournerons.

    # "gauche" indique combien de milliers, de# centaines ou de dizaines il y a.# "ecrire" est la partie que nous crivons droite.# ecrire et gauche... a va ? :)gauche = nombreecrire = gauche/100 # Combien de centaines doit-on crire

    # gauche?gauche = gauche - ecrire*100 # On enlve ces centaines.

    if ecrire > 0

    return 'cent' endecrire = gauche/10 # Combien de dizaines doit-on crire

    # gauche?gauche = gauche - ecrire*10 # On soustrait ces dizaines.

    if ecrire > 0

    if ecrire == 1 # Ehh...# Puisque nous ne pouvons crire "dix-deux" la place# de douze nous devons faire une exception pour ces# nombres.

    if gauche == 0

    chaineNombre = chaineNombre + 'dix' elsif gauche == 1chaineNombre = chaineNombre + 'onze'

    elsif gauche == 2chaineNombre = chaineNombre + 'douze'

    elsif gauche == 3chaineNombre = chaineNombre + 'treize'

    elsif gauche == 4chaineNombre = chaineNombre + 'quatorze'

    elsif gauche == 5chaineNombre = chaineNombre + 'quinze'

    elsif gauche == 6chaineNombre = chaineNombre + 'seize'

    elsif gauche == 7chaineNombre = chaineNombre + 'dix-sept'

    elsif gauche == 8chaineNombre = chaineNombre + 'dix-huit'

    elsif gauche == 9chaineNombre = chaineNombre + 'dix-neuf'

    end# Puisque nous avons dj tenu compte du premier chiffre,# nous n'avons rien crire gauche.gauche = 0

    elsif ecrire == 2chaineNombre = chaineNombre + 'vingt'

    50

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    51/79

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    52/79

    # compris entre 0 et 100, nous devons donc retourner# "chaineNombre".chaineNombre

    end

    puts nombreBelge( 0)puts nombreBelge( 9)puts nombreBelge( 10)puts nombreBelge( 11)puts nombreBelge( 17)puts nombreBelge( 32)puts nombreBelge( 88)puts nombreBelge( 99)puts nombreBelge(100)

    zroneuf

    dixonzedix-septtrente-deuxhuitante-huitnonante-neufcent

    Bon, il y a quelques toutes petites choses que je n'aime pas dans ce programme. Pre-mirement il y a trop de rptitions. Deuximement il n'accepte pas les nombres

    suprieurs 100. Troisimement il y a trop de cas spciaux, trop de returns. Utilisonsquelques tableaux et essayons de nettoyer un peu tout a :

    def nombreBelge nombre if nombre < 0 # Pas de nombres ngatifs. return 'SVP entrez un nombre positif.' end if nombre > 1999 return 'SVP entrez un nombre infrieur 2000.' end

    if nombre == 0 return 'zro' end# Plus de cas spciaux (ou presque...), plus de return.

    chaineNombre= '' # C'est la chane de retour.

    unite= ['un','deux', 'trois', 'quatre', 'cinq',

    'six', 'sept', 'huit', 'neuf']dizaine = ['dix', 'vingt', 'trente', 'quarante', 'cinquante',

    'soixante', 'septante', 'huitante', 'nonante']

    onzadixneuf = ['onze', 'douze', 'treize', 'quatorze','quinze', 'seize', 'dix-sept', 'dix-huit',

    52

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    53/79

    'dix-neuf']# "gauche" indique combien de dizaines, centaines etc...# "ecrire" est la partie que nous crivons droite.# ecrire et gauche... a va ? :)

    gauche = nombreecrire = gauche/100 # Combien de centaines crire?gauche =gauche- ecrire*100 # On soustrait ces centaines.

    if ecrire > 0# Ici se trouve la subtilit :centaines = nombreBelge ecrire

    if centaines == 'un' # On ne dit pas "un cent" mais# "cent" tout court.

    centaines = ''chaineNombre = 'cent'

    elsifchaineNombre = chaineNombre + centaines + ' cent'

    end# C'est ce qu'on appelle la "rcursivit".# De quoi s'agit-il au juste ?# Je dis cette mthode de s'appeler elle-mme,# mais avec "ecrire" au lieu de "nombre".# Souvenez-vous que "ecrire" est (en ce moment)# le nombre de centaines que nous avons crire.# Ensuite nous ajoutons "centaines" "chaineNombre",# nous ajoutons la chane 'cent' aprs.# Ainsi, par exemple, si nous avons appel nombreBelge

    # avec 1999 (tel que "nombre" = 1999),# ce point "ecrire" vaudra 19, et"gauche" vaudra 99.# La chose la plus simple prsent est de laisser# nombreBelge ecrire le 'dix-neuf' pour nous, puis# d'crire 'cent', et nombreBelge ecrira 'nonante-neuf'.

    if gauche> 0# Nous ne voulons pas crire 'deux centcinquante-un...chaineNombre = chaineNombre + ' '

    end endecrire = gauche/10 # Combien de dizaines ?gauche =gauche- ecrire*10 # On enlve les dizaines.

    if ecrire > 0

    if ((ecrire == 1) and (gauche > 0))# Puisque nous ne pouvons crire "dix-deux" au lieu de# "douze", nous devons faire encore une exception.

    chaineNombre = chaineNombre + onzadixneuf[gauche-1]

    # "-1" parce que onzadixneuf[3] est 'quatorze', et non

    # 'treize'. Puisque nous avons dj tenu compte du# premier chiffre, nous n'avons rien crire gauche.

    53

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    54/79

    gauche= 0 else

    chaineNombre = chaineNombre + dizaine[ecrire-1]# "-1" parce que dizaine[3] est 'quarante', et non# 'trente'.

    endif gauche> 0# Nous ne pouvons crire 'soixantequatre'...chaineNombre = chaineNombre + '-'

    end endecrire =gauche # Combien d'units crire ?gauche = 0 # Il ne reste plus rien.

    if ecrire > 0chaineNombre = chaineNombre + unite[ecrire-1]# Le "-1" est l parce que unite[3] reprsente 'quatre'# et non 'trois'.

    end# Maintenant nous retournons "chaineNombre"...chaineNombre

    end

    puts nombreBelge(0)puts nombreBelge(9)

    puts nombreBelge(10)puts nombreBelge(11)puts nombreBelge(17)puts nombreBelge(32)puts nombreBelge(88)puts nombreBelge(99)puts nombreBelge(100)puts nombreBelge(101)puts nombreBelge(234)puts nombreBelge(899)puts nombreBelge(1999)

    zroneufdixonzedix-septtrente-deuxhuitante-huitnonante-neufcentcent undeux cent trente-quatrehuit cent nonante-neufdix-neuf cent nonante-neuf

    54

  • 8/8/2019 Apprendre a Programmer Avec Ruby

    55/79

    Ahhh! Voil qui est mieux, beaucoup mieux. Le programme est plus dense, ce qui m'a per-mis de mettre des commentaires. Il fonctionne pour des nombres plus grands...mais pasautant que vous l'espriez n'est-ce pas? Essayez nombreBelge(1000)... En fait voustes maintenant capable d'arranger le programme tout(e) seul(e).

    Quelques petites choses essayer

    Amliorez nombreBelge en rajoutant tout d'abord les milliers. Il devra donc dire"mille neuf cent nonante-neuf".

    Amliorez ensuite en rajoutant les m