Cours gratuits » Cours informatique » Cours développement web » Cours Ruby » Cours informatique d Introduction au Ruby on Rails

Cours informatique d Introduction au Ruby on Rails

Problème à signaler:

Télécharger



★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Cours informatique d Introduction au Ruby on Rails

...

Le langage Ruby a été conçu, au milieu des années 90, par Yukihiro Matsumoto, un programmeur Japonais. Son objectif était d’avoir un langage qui soit « plaisant» à utiliser :

Ruby is “made for developer happiness”!

  1. Matsumoto
  2. Matsumoto s’est inspiré de plusieurs langages de programmation : Perl [WCS96] (pour le traitement de texte et les expressions régulières) Smalltalk [Gol89] (pour ses blocs et pour son approche orientée objet «pure» où tout est objet), CLU
[LG86] (pour ses itérateurs), Lisp [Ste84] (pour ses fonctions d’ordre supérieur). La figure

1 présente un arbre généalogique de Ruby. Quant au tableau 1, il présente les «ancêtres» de Ruby, avec les principales caractéristiques héritées de ces ancêtres.

Langage Année Caractéristiques

Lisp 1958 approche fonctionnelle

Méta programmation

CLU 1974 itérateurs

Smalltalk 1980 langage objet pur, blocs de code

GUI, sUnit

Eiffel 1986 Uniform Access Principle

Perl 1987 expressions régulières et pattern matching

Ruby 1993

Tableau 1: Les ancêtres de Ruby.

Ruby a été popularisé notamment par le développement de Ruby on Rails [Dix11,

Har13, Lew15, RTH13], un framework pour la mise en oeuvre et le déploiement d’applications Web.

Ruby, comme Perl et Python [Bla04], est un langage à typage dynamique — un langage dit de «script» — avec une syntaxe flexible (on verra comment plus loin) :

Ruby. . . est un langage open-source dynamique qui met l’accent sur la simplicité et la productivité. Sa syntaxe élégante en facilite la lecture et l’écriture. .

$ rvm list known

# MRI Rubies

[ruby-]1.8.6[-p420]

[ruby-]1.8.7[-head] # security released on head

[ruby-]1.9.1[-p431]

[ruby-]1.9.2[-p330]

[ruby-]1.9.3[-p551]

[ruby-]2.0.0[-p643]

[ruby-]2.1.4

[ruby-]2.1[.5]

[ruby-]2.2[.1]

[ruby-]2.2-head

ruby-head

# JRuby

jruby-1.6.8

jruby[-1.7.19]

jruby-head

jruby-9.0.0.0.pre1

# Rubinius

rbx-1.4.3

rbx-2.4.1

rbx[-2.5.2]

rbx-head

# Opal

opal

# Minimalistic ruby implementation - ISO 30170:2012

mruby[-head]

# Ruby Enterprise Edition

ree-1.8.6

ree[-1.8.7][-2012.02]

# GoRuby

goruby

# Topaz

topaz

# MagLev

maglev[-head]

maglev-1.0.0

# Mac OS X Snow Leopard Or Newer

macruby-0.10

macruby-0.11

macruby[-0.12]

macruby-nightly

macruby-head

# IronRuby

ironruby[-1.1.3]

ironruby-head

Figure 2: Les mises en oeuvre de Ruby disponibles par l’intermédiaire de rvm (février 2016) — voir annexe A .

Il existe plusieurs mises en oeuvre de Ruby, par exemple, MRI (Matz’s Ruby Interpreter, parfois appelé CRuby car sa mise en oeuvre est en langage C), Rubinius (mise en oeuvre. . . en Ruby), JRuby (mise en oeuvre en Java sur la JVM = Java Virtual Machine). Dans ce qui suit, nous allons introduire le langage Ruby par l’intermédiaire de divers exemples. Dans certains exemples, jruby est utilisé pour évaluer certaines expression, mais ces expressions auraient tout aussi bien pu être évaluées avec ruby/MRI.

2 Compilation et exécution de programmes Ruby

Exemple Ruby 1 Deux versions d’un programme «Hello world!».

$ cat hello0 . rb

puts ’Bonjour le monde !’

$ ruby hello0 . rb

Bonjour le monde !

------------------------------------

$ cat hello1 . rb

#!/ usr / bin /env ruby

puts ’Bonjour le monde !’

$ ls -l hello1 . rb

-rwxr -xr -x . 1 tremblay tremblay 46 26 jun 09:52 hello1 . rb *

$ ./ hello1 . rb

Bonjour le monde !

Remarques et explications pour l’exemple Ruby 1 :

  • L’instruction puts (putstring) affiche la chaîne indiquée en argument sur la sortie standard (STDOUT) et ajoute un saut de ligne — on peut utiliser «print» pour ne pas ajouter automatiquement un saut de ligne.
  • Ruby étant un langage dynamique — on dit aussi un «langage de script» — la compilation et l’exécution se font à l’aide d’une seule et même commande :

– À l’aide d’un appel explicite à la commande ruby : «ruby hello0.rb».

– À l’aide d’un appel implicite à la commande ruby : «./hello1.rb», la première ligne (débutant par «#!») de hello1.rb indiquant que le script doit être compilé et exécuté avec ruby.

  • Bien qu’on parle souvent d’un processus «d’interprétation», les versions plus récentes de Ruby utilisent un compilateur : une première passe analyse et compile le programme pour générer du code-octet, puis ce code-octet est exécuté par la machine virtuelle de Ruby (ou par la JVM dans le cas de JRuby).

3 irb : Le shell interactif Ruby

Exemple Ruby 2 irb, le shell interactif de Ruby.

$ irb --prompt=simple

>> 10

=> 10

>> 2 + 4

=> 6

>> puts ’Bonjour le monde !’

Bonjour le monde !

=> nil

>> r = puts ’Bonjour le monde !’

Bonjour le monde !

=> nil

>> r

=> nil

>> puts ( ’Bonjour le monde !’ )

Bonjour le monde !

=> nil

>> STDOUT . puts ( ’Bonjour le monde !’ )

Bonjour le monde !

=> nil

>> STDERR . puts ( ’Bonjour le monde !’ )

Bonjour le monde !

=> nil

>> STDIN . puts ( ’Bonjour le monde !’ )

IOError : not opened for writing

from org / jruby / RubyIO . java :1407: in ‘ write ‘

[...]

from / home / tremblay /. rvm / rubies / jruby -1.7.16.1/ bin / irb :13: in ‘( root )’

Remarques et explications pour l’exemple Ruby 2 :

  • Une autre façon d’exécuter du code Ruby est d’utiliser irb — interactive Ruby.
  • Le processus d’évaluation d’irb — le REPL = Read-Eval-Print-Loop — procède comme suit :

– À l’invite de commande (prompt) indiquée par «>> », on entre une expression

— par ex., «>> 2 + 4».1

– L’expression est évaluée.

– Le résultat retourné par l’expression est affiché après le symbole «=>» — par ex., «=> 6».

  • Le premier exemple de puts montre que si l’expression évaluée affiche quelque chose sur STDOUT, alors cela s’affiche avant que le résultat retourné par l’expression ne soit affiché. On note aussi que le résultat retourné par un appel à puts est nil.
  • Les autres exemples illustrent ce qui suit :

– Dans un appel de méthode, les parenthèses — à moins qu’il n’y ait ambiguité à cause de la précédence des opérateurs : voir plus bas — peuvent être omises. Donc, un appel tel que «puts ’xxx’» est équivalent à l’appel «puts( ’xxx’ )».

– Un appel direct à puts est équivalent à un appel de puts sur STDOUT, la constante qui dénote le flux standard de sortie. Lors d’une session interactive irb, tant STDOUT que STDERR sont associés à l’écran. Quant au flux d’entrée STDIN, il est aussi disponible et est associé par défaut au clavier, donc il ne peut évidemment pas être utilisé pour effectuer des écritures.

Dans plusieurs des exemples qui suivent, ce sont les résultats produits avec irb qui seront affichés, bien que dans certains cas les détails affichés seront quelque peu simplifiés pour faciliter la lecture des exemples.

4 Tableaux

Exemple Ruby 3 Les tableaux et leurs opérations de base.

>> # Valeurs litterales , indexation et taille .

?> a = [10 , 20 , 30]

=> [10 , 20 , 30]

>> a [0]

=> 10

>> a [2]

=> 30

>> a [2] = 55

=> 55

>> a

=> [10 , 20 , 55]

>> a. size

=> 3

?> # Valeur nil par defaut et extension de la taille .

?> a [6]

=> nil

>> a. size

=> 3

>> a [5] = 88

=> 88

>> a

=> [10 , 20 , 55 , nil , nil , 88]

>> a. size

=> 6

?> # Acces au ’dernier ’ element .

?> a[ a. size -1]

=> 88

>> a [ -1]

=> 88

Remarques et explications pour l’exemple Ruby 3 :

  • Un commentaire débute par «#» et se termine à la fin de la ligne. Une ligne ne contenant qu’un commentaire n’a donc pas d’expression à évaluer et, dans irb, l’entrée se continue à la ligne suivante avec le prompt de continuation

(«?> »).

Il est possible d’indiquer un commentaire formé par un bloc de lignes — bien que ce soit utilisé assez peu fréquemment sauf pour certaines formes de documentation

(e.g., RDoc) :

= begin

Blah blah

...

= end

  • L’indice du premier élément d’un tableau, comme en C et en Java, est 0.
  • Un tableau a est automatiquement étendu à la taille appropriée si on affecte à un indice plus grand ou égal à a.size. Les valeurs non explicitement définies sont alors égales à nil.
  • L’indice du dernier élément d’un tableau a est a.size-1. On peut aussi accèder au dernier élément avec l’indice -1, à l’avant-dernier avec l’indice -2, etc.

Exemple Ruby 4 Les tableaux et leurs opérations de base (suite 1).

?> # Tableaux heterogenes .

?> a

=> [10 , 20 , 55 , nil , nil , 88]

>> a [8] = ’abc ’

=> " abc "

>> a

=> [10 , 20 , 55 , nil , nil , 88 , nil , nil , " abc "]

Remarques et explications pour l’exemple Ruby 4 :

  • Les tableaux sont hétérogènes, i.e., ils peuvent contenir des éléments de types variés.

?> # Ajout d’elements .

?> a = []

=> []

>> a << 12

=> [12]

>> a << ’abc ’ << [2.7 , 2.8]

=> [12 , "abc ", [2.7 , 2.8]]

?> # Creation de tableaux avec valeurs initiales .

?> b = Array . new (3) { 10 }

=> [10 , 10 , 10]

>> d = Array . new (4)

=> [nil , nil , nil , nil ]

  • Il existe de nombreuses opérations pour ajouter ou retirer des éléments d’un tableau, par exemple, push, pop, shift, unshift, etc.2
  • Une opération fréquemment utilisée est push, qui a comme alias «<<».
  • L’opération new permet de créer un tableau d’une certaine taille de départ et permet aussi de spécifier, de façon optionnelle, une valeur initiale pour les différents éléments du tableau.

Exemple Ruby 5 Les tableaux et leurs opérations de base (suite 2).

?> # Tranches de tableaux .

?> a = [10 , 20 , 30 , 40 , 50]

=> [10 , 20 , 30 , 40 , 50]

>> a [0..2]

=> [10 , 20 , 30]

>> a [3..3]

=> [40]

>> a [1.. -1]

=> [20 , 30 , 40 , 50]

>> a [7..7]

=> nil

?> # Intervalles inclusifs vs. exclusifs

>> a

=> [10 , 20 , 30 , 40 , 50]

>> a [1..3]

=> [20 , 30 , 40]

>> a [1...3]

=> [20 , 30]

>> a [1.. a. size -1]

=> [20 , 30 , 40 , 50]

>> a [1... a . size ]

=> [20 , 30 , 40 , 50]

Remarques et explications pour l’exemple Ruby 5 :

  • On peut obtenir une tranche d’un tableau en spécifiant comme indice un Range. Un Range avec «..» est inclusif — par ex., b_inf..b_sup — donc inclut tant la borne inférieure que la borne supérieure. Par contre, un Range avec «...» est exclusif, i.e., inclut la borne inférieure mais exclut la borne supérieure.

5 Chaînes de caractères

Exemple Ruby 6 Les chaînes de caractères et leurs opérations de base.

>> # String semblable a Array .

?> s1 = ’abc ’

=> " abc "

>> s1 . size

=> 3

>> s1 [0..1] # Retourne String .

=> "ab"

>> s1 [2] # Retourne String aussi !

=> "c"

?> # Concatenation vs. ajout .

?> s1 + ’def ’

=> " abcdef "

>> s1

=> " abc "

>> s1 << ’def ’

=> " abcdef "

>> s1

=> " abcdef "

Remarques et explications pour l’exemple Ruby 6 :

  • Un String est, par certaines opérations, semblable à un Array, notamment, on peut l’indexer pour obtenir un élément ou une sous-chaîne.
  • L’indexation d’un String. . . retourne un String, 3 que l’indice soit un Range ou un Fixnum.
  • L’opération «+» concatène deux chaînes pour produire une nouvelle chaîne (opération fonctionnelle, immuable) alors que l’opérateur «<<» ajoute (append) des caractères à la fin d’une chaîne existante (opération impérative, mutable).

Exemple Ruby 7 Les chaînes de caractères et leurs opérations de base (suite).

>> # Egalite de valeur * sans * partage de reference .

?> a , b = ’abc ’, ’abc ’

=> [" abc", "abc "]

>> a == b

=> true

>> a. equal ? b

=> false

>> a [0] = ’X’

=> "X"

>> a

=> " Xbc "

>> b

=> " abc "

?> # Egalite de valeur * avec * partage de reference .

?> a = b = ’abc ’

=> " abc "

>> a == b

=> true

>> a. equal ? b

=> true

>> a [0] = ’X’

=> "X"

>> a

=> " Xbc "

>> b

=> " Xbc "

Remarques et explications pour l’exemple Ruby 7 :

  • Ruby possède plusieurs opérations de comparaison d’égalité. Les deux premières sont les suivantes :

– «==» : Comparaison de valeur. C’est généralement cette opération que l’on spécifie dans les classes que l’on définit nous-mêmes.

– «equal?» : Comparaison d’identité, i.e., est-ce que les deux éléments comparés dénotent le même objet (le même pointeur, la même référence)?

Note : La signification de ces opérateurs est l’inverse de celle de Java, où «==» est la comparaison d’identité alors que equals est la comparaison de valeur.

  • En Ruby, il est considéré de bon style qu’une méthode qui retourne un booléen se termine par «?», par exemple, equal?, empty?, nil?, block_given?, etc.

Exemple Ruby 8 Interpolation d’une expression dans une chaîne.

>> # Interpolation d’une expression dans une chaine .

?> x = 123

=> 123

?> " abc \"#{ x}\" def "

=> " abc \"123\" def "

?> " abc ’#{10 * x + 1} ’ def "

=> " abc ’1231 ’ def "

?> " abc #{x > 0 ? ’++ ’ : 0} def "

=> " abc ++ def "

?> # Une String peut etre definie avec ’... ’ mais sans interpolation .

?> ’abc "#{ x}" def ’

=> " abc \"\#{ x}\" def "

Remarques et explications pour l’exemple Ruby 8 :

  • Une chaîne produite avec les doubles guillemets permet d’interpoler une ou des expressions. Dans une telle chaîne, «#{...}» indique alors une expression qui doit être évaluée — on dit aussi interpolée. Si cette expression produit un résultat qui n’est pas une chaîne, alors la méthode to_s sera implicitement appelée — voir plus bas.
  • On peut aussi définir une chaîne avec de simples guillemets, mais dans ce cas aucune interpolation n’est effectuée (chaine textuelle).

Donc, les guillemets doubles vs. apostrophes simples ont la même interprétation

qu’en bash!

Exemple Ruby 9 Opérations split et join.

# Split decompose une chaine en sous - chaines

# en fonction du <<motif > > specifie en argument .

>> s = "abc \ ndef \ nghi \n"

=> " abc \ ndef \ nghi \n"

>> s. split ("\n") # Un cas typique !

=> [" abc ", "def ", " ghi "]

>> s. split ("def ")

=> [" abc \n", "\ nghi \n"]

>> s. split ("a")

=> ["", "bc\ ndef \ nghi \n"]

>> s. split (/\ w {3}/) # \w = [a-zA -Z0 -9_]

=> ["", "\n", "\n", "\n"]

# Join combine un tableau de sous - chaines

# en une chaine unique .

>> s

=> " abc \ ndef \ nghi \n"

>> r = s. split ("\n")

=> [" abc ", "def ", " ghi " ]

>> r. join ("+")

=> " abc +def +ghi "

>> r. join ("\n") # Donc : s. split ("\ n "). join ("\ n") != s

=> " abc \ ndef \ nghi "

>> []. join (";")

=> ""

>> [’abc ’]. join (";")

=> " abc "

>> [’abc ’, ’def ’]. join (";")

=> " abc ;def "

Remarques et explications pour l’exemple Ruby 9 :

  • La méthode split décompose une chaine pour produire un tableau de souschaines, et ce en utilisant le séparateur indiqué.
  • Le séparateur peut être un caractère, une chaine ou une expression régulière.

Les séparateurs ne font pas partie des sous-chaines retournées par split.

  • Une sous-chaine peut être la chaine vide ("") si la chaine continent deux séparateurs consécutifs ou si la chaine débute ou se termine par un séparateur.
  • La méthode join reçoit un tableau de chaines et les combine en une seule chaine en utilisant la chaine indiquée.

6 Symboles

Exemple Ruby 10 Les symboles.

>> # Symbole = " sorte " de chaine * unique et immuable *.

>> : abc

=> : abc

>> : abc . class

=> Symbol

>> : abc . to_s

=> " abc "

>> puts : abc

abc

=> nil

>> : abc [2]

=> "c"

>> : abc [2] = "x"

NoMethodError : undefined method ‘[]= ’ for : abc : Symbol

from (irb ):4

from / home / tremblay /. rvm / rubies /ruby -2.1.4/ bin / irb :11: in ‘<main >’

>> " abc ". to_sym

=> : abc

>> " abc def .!#% ". to_sym

=> :" abc def .!#% "

Remarques et explications pour l’exemple Ruby 10 :

  • Un symbole — classe Symbol — est une représentation unique d’un identificateur.
  • Un identificateur débutant par «:» est un symbole.
  • Un symbole est une sorte de chaîne mais unique et immuable.

Ainsi, bien que deux chaînes peuvent avoir la même valeur tout en étant distinctes l’une de l’autre — ch1 == ch2 mais !(ch1.equal? ch2) — ce n’est pas le cas avec les symboles — sym1 == sym2 implique sym1.equal? sym2.

?> # Possede un numero d’ identification unique .

>> :a

=> :a

>> :a . object_id

=> 365128

>> "a". object_id

=> 11000000

>> "a". object_id

=> 10996280

>> :a . object_id

=> 365128

>> "a". to_sym . object_id

=> 365128

?> # Egalite de valeur vs. de reference .

?>

>> : abc == : abc

=> true

>> : abc . equal ? : abc

=> true

>> " abc " == "abc "

=> true

>> " abc ". equal ? "abc "

=> false

>> " abc ". to_sym == "abc ". to_sym

=> true

>> " abc ". to_sym . equal ? "abc ". to_sym

=> true

  • On peut obtenir le symbole associé à une chaîne arbitraire à l’aide de la méthode to_sym.
  • On peut observer l’unicité d’un symbole en obtenant son object_id — un entier qui identifie de façon unique n’importe quel objet (≈ l’adresse de l’objet en mémoire!).

Deux chaines peuvent être égales mais ne pas être le même objet, donc avoir deux object_id distincts. Par contre, chaque référence à un symbole retourne toujours le même object_id.

  • Les symboles sont souvent utilisés comme clés pour les hashes, de même que pour les keyword arguments — voir plus bas.

7 Hashes

Exemple Ruby 11 Les hashes et leurs opérations de base.

>> # Definition d’un hash .

?> hash = { : abc = > 3 , : de = > 2 , : ghijk => 5 }

=> {: abc = >3 , : de = >2 , : ghijk = >5}

?> # Principales proprietes .

?> hash . size

=> 3

>> hash . keys

=> [: abc , : de , : ghijk ]

>> hash . values

=> [3 , 2 , 5]

?> # Indexation .

?> hash [: abc ]

=> 3

>> hash [: de ]

=> 2

>> hash ["de"]

=> nil

Exemple Ruby 12 Les hashes et leurs opérations de base (suite).

?> # Definition d’une nouvelle cle .

?> hash . include ? "de"

=> false

>> hash ["de"] = 55

=> 55

>> hash . include ? "de"

=> true

?> # Redefinition d’une cle existante .

?> hash [: abc ] = 2300

=> 2300

>> hash

=> {: abc = >2300 , : de = >2 , : ghijk = >5 , "de"= >55}


102