Programmation Ruby/Types standards
Nous allons voir ici tous les types que nous pouvons considérer comme "standards", dans le sens où nous les retrouvons dans la plupart des langages, et que ceux-ci sont directement intégrés à l'interpréteur ("built-in"). Néanmoins il ne faut pas perdre de vue qu'il s'agit en réalité d'objets.
Pour rappel les méthodes dont le nom se termine par "!" sont non pures : elles modifient l'objet.
Chaîne de caractères.
En ruby les chaînes de caractères sont représentées par l'objet "String". En réalité cet objet contient et permet la manipulation d'un nombre indéfini d'octets, typiquement des caractères, nous pourrons néanmoins y stocker tout type de données binaires ou non.
Créer une chaîne de caractères.
En ruby il existe une multitude de manières de créer une chaîne de caractères, par exemple en créant une instance de l'objet "String" :
 maChaine = String.new("Une chaîne de caractères")
Mais le moyen le plus courant de créer une chaîne est de la placer entre simple quote (') ou entre double quote ("). Néanmoins ces deux moyens ne sont pas équivalents : en utilisant les doubles quotes ruby évaluera les expressions contenues entre "#{" et "}", ainsi que les caractères d'échappements.
 i = 100
 puts "la valeur de i est \n #{i}"
 => La valeur de i est
 100
 puts 'la valeur de i est \n #{i}'
Dans une chaîne de caractère "\" a une valeur particulière, elle permet de placer un caractères d'échappements. Le caractère "\" indique à ruby que le caractère suivant possède une valeur particulière : ainsi "\n" représente une nouvelle ligne. Les caractères d'échappements ne sont pas pris en compte avec une chaîne de caractères débutant par un simple quote, néanmoins nous pouvons l'utiliser pour indiquer à Ruby de considérer le simple quote ou le backslash suivant comme faisant partie de la chaîne :
 puts 'un simple quote : \' qui ne ferme pas la chaîne, et ici un backslash : \\'
 => un simple quote : ' qui ne ferme pas la chaîne, et ici un backslash : \
Un autre moyen de créer une chaîne est d'utiliser "%q" ou "%Q", qui équivalent respectivement au simple et au double quote. Néanmoins l'utilisation de "%q" ou "%Q" permet de définir le caractère d'ouverture et de fermeture de la chaîne :
 %q!j'utilise le caractère \! pour ouvrir ou fermer la chaîne, ' et " peuvent ainsi être utilisés sans \ !
 %q*je peux utiliser n'importe quel caractère non alpha-numérique qui n'est pas dans la chaîne elle même*
Si nous avons plusieurs lignes de texte à écrire nous pouvons utiliser les caractères "«" suivit d'un identifiant pour créer une chaîne ayant les mêmes propriétés qu'une chaîne entre double quote, ou les caractères "«-" suivis d'un identifiant entre simple quote pour créer une chaîne de caractères ayant les mêmes propriétés qu'une chaîne entre simple quote :
 i = 100
 maChaine «DEBUT
 une chaîne de caractères
 DEBUT
 => une chaîne de caractères
 i vaut 100
 i = 100
 maChaine «-'DEBUT'
 une chaîne de caractères
 DEBUT
 => une chaîne de caractères
Le dernier moyen d'obtenir une chaîne de caractères est d'utiliser la méthode "to_s" que la plupart des objets implémentent, ainsi :
 42.to_s => "42"
Comparaisons de chaînes.
Les chaînes de caractères peuvent être comparées comme indiqué dans le chapitre Expressions booléennes grâce aux méthodes "<, <=, ==, >=, >"
 "abcdef" <=> "abcde" => 1
 "abcdef" <=> "abcdef" => 0
 "abcdef" <=> "abcdefg" => -1
 "abcdef" <=> "ABCDEF" => 1 # Les caractères minuscules sont supérieurs aux caractères majuscules
 "abc" <=> "acc" => -1
 "a" < "b" => true
 "a" < "a" => false
 "a" > "b" => false
 "a" > "a" => false
 "a" <= "b" => true
 "a" <= "a" => true
 "a" >= "b" => false
 "a" >= "a" => true
 "a" == "a" => true
 "a" == "b" => false
 "a" != "a" => false
 "a" != "b" => true
La méthode est équivalente à "<=>", à part que la casse n'est pas comparée :
 "abcdef".casecmp("ABCDEF") => 0
Manipulation de chaînes.
Taille d'une chaîne et index des caractères.
length.
"length" permet de connaître la taille d'une chaîne de caractères :
"Bonjour le monde".length => 16
index et rindex.
"index" renvoie l'index de la première occurrence d'une sous chaîne dans la chaîne de caractères, renvoi "nil" si aucune occurrence n'a été trouvée :
 "hello".index('e') => 1
 "hello".index('lo') => 3
 "hello".index('a') => nil
Si un entier est donné en second paramètre, celui-ci indique l'index où commencer la recherche.
 "Bonjour le monde".index('o',7) => 12
Nous pouvons également utiliser une expression rationnelle.
"rindex" effectue le même travail à la différence près que la recherche se fait à partir de la fin de la chaîne de caractères :
 "Bonjour le monde".rindex('o') => 12
Si le second paramètre est présent, la recherche commencera au caractère indiqué :
 "Bonjour le monde".rindex('o',9) => 4
À noter que si le second paramètre est négatif, alors l'index est compté à partir de la fin de la chaîne :
 "Bonjour le monde".rindex('o',-9) => 4
 "Bonjour le monde".rindex('o',-2) => 12
Opérateurs sur les chaînes de caractères.
L'opérateur de multiplication renvoie une chaîne de caractères contenant "n" fois la chaîne représentée par l'objet :
"Ho! " * 3 => Ho! Ho! Ho!
L'opérateur d'addition permet de concaténer deux chaînes de caractères :
 maChaine = "le Monde"
 "Bonjour " + maChaine => Bonjour le Monde
[] et []=.
L'opérateur "[]" permet de récupérer un ou plusieurs caractères faisant partie d'une chaîne.
Si un entier est passé en paramètre, l'opérateur renverra le code ASCII du caractère correspondant (le premier caractère est indexé par la valeur 0) :
 maChaine = "Bonjour le monde"
 maChaine[3] => 106 # Correspond au code ASCII du 4e caractère (j)
Si deux entiers sont passés en paramètres, l'opérateur renverra une sous-chaîne commençant à l'index passé en premier paramètre et de longueur indiquée par le second élément :
 maChaine[1,5] => onjou
On peut également indiquer un intervalle :
 maChaine[1..6] => onjou
Il est à noter que si l'index est négatif, ruby compte à partir de la fin de la chaîne :
 maChaine[-3,5] => nde
On peut également utiliser une expression rationnelle, nous verrons cela plus en détail dans le chapitre correspondant.
L'opérateur "[]=" permet de changer le contenu d'une chaîne de caractères. L'utilisation est semblable à celle de "[]", à la différence que plutôt que de renvoyer un ensemble de caractères, l'opérateur modifiera la chaîne :
 maChaine[3] = "V"
 puts maChaine => BonVour le monde
 maChaine[8] = "tout "
 puts maChaine => Bonjour tout le monde
Si deux entiers sont passés en paramètres, ruby remplacera la chaîne commençant à l'index passé en première paramètre et d'une longueur passée en second paramètre :
 maChaine[8,8] = "Roger" 
 puts maChaine => Bonjour Roger 
 maChaine[8..16] = "Roger"
 puts maChaine => Bonjour Roger
On peut directement utiliser une chaîne de caractères ou une expression rationnelle :
 maChaine["Bonjour"] = "Hello"
 puts maChaine => Hello le monde
Formatage de chaîne.
split.
"split" permet de séparer les différents éléments d'une chaîne en fonction d'un ou plusieurs délimiteurs, par défaut ceux-ci sont les fins de ligne et les espaces ("\s", "\t", "\r","\n" et "\r\n"). La méthode renvoi un tableau contenant les différents éléments :
 "Bonjour le monde".split => ["Bonjour", "le", "monde"]
 "B.o.n.j.o.u.r".split('.') => ["B","o","n","j","o","u","r"]
Si un entier est donné en paramètre, le tableau résultant n'aura comme nombre d'éléments la valeur de cet entier :
 "B.o.n.j.o.u.r".split('.',3) => ["B","o","n.j.o.u.r"]
Nous pouvons également utiliser une expression rationnelle.
chomp, chomp!, chop et chop!
"chop" et "chop!" permettent de supprimer le dernier caractère d'une chaîne, néanmoins si les deux derniers caractères sont "\r\n", les deux caractères sont supprimés :
 "Bonjour\r\n".chop => "Bonjour"
 "Bonjour\n\r".chop => "Bonjour\n"
 "Bonjour\n".chop => "Bonjour"
 "Bonjour".chop => "Bonjou"
"chomp" et "chomp!" suppriment le dernier caractère seulement si celui-ci est un caractère de fin de ligne (soit ""\r", "\n" et "\r\n"") :
 "Bonjour".chomp => "Bonjour"
 "Bonjour\n".chomp => "Bonjour"
 "Bonjour \n le monde".chomp => "Bonjour \n le monde"
Si une chaîne de caractères est donnée en paramètre, celle-ci est supprimée si elle est termine la chaîne :
 "Bonjour".chomp("jour") => "Bon"
 "Bonjour\r\n".chomp("jour") => "Bonjour\r\n"
Pour rappel, les méthodes finissant par "!" sont des méthodes non pures : elles modifient l'objet appelant.
downcase, downcase!, upcase, upcase!, swapcase, swapcase!, capitalize et capitalize!
"downcase" et "upcase" permettent de passer respectivement tous les caractères en majuscules ou en minuscules.
 "BonjOUr".downcase => "bonjour"
 "BonjOUr".upcase => "BONJOUR"
"swapcase" inverse la casse :
 "BonjOUr".swapcase => "bONJouR"
"capitalize" ne met que le premier caractère en majuscule :
 "bonjOUr".capitalize => "Bonjour"
L'opérateur "%" permet de formater la chaîne de caractères. Le format utilisé est le même que celui de la fonction "sprintf" de ruby et de bien d'autres langages tel le "C". Le format est décrit par le caractère "%" suivi d'un indicateur optionnel, un indicateur de taille, de précision et de type.
Les indicateurs de type :
Format :
 "%.3s" % 42424242 => "424"
Si plusieurs éléments doivent être formatés, il faut passer les paramètres dans un tableau :
 "%d %04x" % [12.5, 42] => "12 002a"
unpack.
La méthode "unpack" permet de décoder des chaînes de caractères (ou contenant des données binaires) en corrélation avec une chaîne de format.
La chaîne de format se compose d'un nombre de directives à piocher dans le tableau précédent, facultativement suivi d'un nombre indiquant le nombre de fois qu'il faut répéter cette directive, un astérisque ("*") correspondant a tous les éléments restant. Les directives "s","S","i","I","l" et "L" peuvent être suivis d'un underscore ("_") indiquant de choisir le format natif du système.
Exemples :
 "abc \0\0abc \0\0".unpack('A6Z6') => ["abc", "abc "]
 "abc \0\0".unpack('a3a3') => ["abc", " \000\000"]
 "aa".unpack('b8B8') => ["10000110", "01100001"]
 "aaa".unpack('h2H2c') => ["16", "61", 97] 
 "\xfe\xff\xfe\xff".unpack('sS') => [-2, 65534] 
 "now=20is".unpack('M*') => ["now is"] 
 "whole".unpack('xax2aX2aX1aX2a') => ["h", "e", "l", "l", "o"]
Itérateurs.
Les itérateurs sont un mécanisme puissant de ruby, ils permettent de parcourir les éléments d'un objet. Nous verrons plus tard comment étendre facilement sa propre classe avec des itérateurs. Pour chaque type que nous allons voir, nous allons voir ses itérateurs. À l'heure actuelle considérons simplement un itérateur comme une méthode prenant un bloc pour paramètre (et d'ailleurs c'est ce que les itérateurs sont : de simples méthodes).
succ, succ! et upto.
"succ" se contente de renvoyer l'élément succédant à la chaîne, en pratique "succ" incrémente le dernier caractère alphanumérique de la chaîne, si celui-ci a atteint sa limite, "succ" incrémentera l'avant-dernier caractère et ainsi de suite:
 "abcd".succ => "abce"
 "THX1138".succ => "THX1139"
 "«koala»".succ => "«koalb»"
 "1999zzz".succ => "2000aaa"
"upto" itère à travers les valeurs successives d'une chaîne, jusqu'à arriver à la chaîne passée en paramètre. La méthode incrémente à partir de la dernière valeur alphanumérique de la chaîne :
 "«aa»".upto("«bb»") do
 |i| puts i
 end
 => «aa»
 «ab»
 «ac»
 «ad»
 «ae»
 «af»
 «ag»
 «ah»
 «ai»
 «aj»
 «ak»
 «al»
 «am»
 «an»
 «ao»
 «ap»
 «aq»
 «ar»
 «as»
 «at»
 «au»
 «av»
 «aw»
 «ax»
 «ay»
 «az»
 «ba»
 «bb»
each_byte.
"each_byte" permet d'itérer à travers la chaîne de caractères, octet par octet. La valeur qui sera envoyée au bloc sera le code ASCII (donc un entier) du caractère :
 "bonjour".each_byte {|i| print i.to_s+" "} => 98 111 110 106 111 117 114
each.
"each" permet d'itérer à travers chaque ligne contenue dans une "String" :
 "H\nA\r\nL\n".each do
 |i| print i.succ
 end => IBM
Il est à noter que l'itérateur "each" est celui appelé par la construction "for".."in' :
 for i in "H\nA\r\nL\r"
 print i.succ
 end
 => IBM
Valeur numérique.
En ruby les valeurs numériques sont soit flottantes soit entières et sont de taille infinie (jusqu'à la limite de mémoire du système).
Plus tôt dans le livre, nous avons indiqué qu'un type entier est de type "Integer". En fait nous avons menti. Le type Integer permet en réalité de cacher le type réel de la valeur. En effet, les valeurs inférieures aux valeurs d'un entier sur le système (donc en général 32 ou 64 bits) sont en réalité de type "Fixnum". Au delà, elles seront de types "Bignum". En pratique la conversion est transparente pour le développeur :
 i = 10
 5.times do
 print i.class,"\n"
 i = i*i
 end
 => Fixnum
 Fixnum
 Fixnum
 Fixnum
 Bignum
Syntaxe.
En ruby une valeur numérique peut s'écrire de différente forme, notamment en fonction de la base utilisée.
Classiquement, une valeur numérique peut s'écrire comme une suite de chiffres séparés éventuellement par des caractères de soulignement ( "_") qui seront ignorés lors de l'interprétation. Une valeur négative est simplement préfixée par le signe moins ("-") :
 42 => 42
 4_2 => 42
 -42 => -42
On peut également travailler dans une autre base en préfixant la valeur numérique. Ainsi en préfixant avec "0" (zéro) on indique l'utilisation d'un nombre en base octale, 0x pour un nombre en hexadécimal et 0b pour un nombre en binaire :
 0767 => 503
 0xaabb => 43707
 0b01101101 => 109
Utilisation.
Un objet correspondant à une valeur numérique s'instancie simplement en écrivant cette valeur :
 4 => 4
 4.class => Fixnum
Certains objets, comme l'objet "String", possèdent une méthode "to_i" qui renvoie si possible une valeur entière, et "to_f" qui renvoi si possible un flottant :
 " 58_87".to_i => 5887
Si la chaîne contient des éléments non numériques, à l'exception du caractère de soulignement ou du signe moins, la valeur renvoyée sera celle de la première valeur numérique trouvée et précédant les autres caractères :
 "toto".to_i => 0
 "to87to".to_i => 0
 "87to".to_i => 87
"Opérateurs" arithmétiques.
Attention : En Ruby les opérateurs n'existent pas, ce sont des méthodes inclusent dans l'objet Ruby père Object.
On parle donc ici d'"opérateur" par analogie avec les langages orientés objet et procéduraux.
il faut bien comprendre que :
 2 + 4 
équivaut à 
 2.+(4)
tel que 
 objet1 = 2
 objet2 = 4
 objet1.+(objet2) => 6
Pour simplifier la lecture, on accordera l'usage de cet abus de langage dans le reste du document pour faciliter le passage d'un autre langage vers Ruby
+.
L'opérateur "+" permet d'additionner 2 valeurs numériques :
 2+2 => 4
 "3+4".to_i => 3
L'opérateur "-" permet de soustraire une valeur numérique à une autre :
 42-10 => 32
 2-10 => -8
L'opérateur "*" permet de multiplier 2 valeurs numériques :
 42*2 => 84
L'opérateur "/" permet de diviser une valeur numérique par une autre :
 9/3 => 3
ATTENTION: Le type renvoyé est du type des opérandes, ainsi si la division n'est pas entière, seul le dividende est renvoyé:
 9/4 => 2
par contre, si nous utilisons au moins un flottant, le type renvoyé sera de type flottant :
 9.0/4 => 2.25
Une division par 0 lève une exception (nous verrons les exceptions plus tard, il suffit de considérer à l'heure actuelle qu'il s'agit d'une erreur) et interrompt le cours du programme si celle-ci n'est pas interceptée :
 9/0 => ZeroDivisionError: divided by 0
L'opérateur "**" permet d'augmenter une valeur numérique à la puissance indiquée en paramètre :
 9**2 => 81
 9**0 => 1
L'opérateur "%" (modulo) permet de connaître le reste d'une division :
 100%30 => 10
Itérateurs.
La classe "Integer " propose également certains itérateurs, comme pour tout autre itérateur, ceux-ci prennent un ou plusieurs paramètres ainsi qu'un bloc de code.
succ.
"succ" permet de récupérer la valeur numérique suivante :
 8.succ => 9
times.
"times" permet de créer une boucle allant de 0 à la valeur de l'objet :
 5.times do |val|
 print val.to_s+'..'
 end
 => 0..1..2..3..4..
upto et downto.
"upto" et "downto" permettent respectivement d'itérer à partir de la valeur de l'objet jusqu'à la valeur passée en paramètre, respectivement en incrémentant ou en décrémentant :
 5.upto(8) do |i| print i.to_s+'..' end
 => 5..6..7..8..
 8.downto(5) do |i| print i.to_s+'..' end
 => 8..7..6..5..
 5.downto(8) do |i| print i.to_s+'..' end
 => 5
step.
"step" ressemble à "upto" et "downto" à part que l'on peut préciser le pas :
 5.step(48, 5) do |i| print i.to_s+'..' end #ici le second paramètre correspond au pas
 => 5..10..15..20..25..30..35..40..45..
Expression rationnelle.
Les expressions rationnelles (parfois nommées à tort expressions régulières) sont un mécanisme puissant mais qui peut être complexe. Elles permettent des recherches dans une chaîne de caractères selon des critères ou un modèle de recherche précis. Ceci permet la sélection d'une sous chaîne de caractères, ou la manipulation des chaînes ainsi trouvées (typiquement une substitution).
Ruby propose une classe pour l'utilisation des expressions rationnelles, les développeurs Perl seront heureux car son utilisation en Ruby est quasi-identique (voir ).