diff --git a/toolbox.md b/toolbox.md new file mode 100644 index 0000000..f1567c8 --- /dev/null +++ b/toolbox.md @@ -0,0 +1,687 @@ +# Toolbox Ruby + +Cette fiche regroupe les méthodes Ruby les plus courantes à connaître ou à savoir retrouver rapidement. + +Certaines méthodes utilisées avec `Array`, `Hash` ou `Range` proviennent en réalité du module `Enumerable`. + +## String + +```ruby +text = "Bonjour Ruby" +``` + +### Informations + +| Méthode | Utilité | Exemple | +|---|---|---| +| `length` / `size` | Nombre de caractères | `text.length` | +| `empty?` | Vérifie si la chaîne est vide | `text.empty?` | +| `include?` | Cherche une sous-chaîne | `text.include?("Ruby")` | +| `start_with?` | Vérifie le début | `text.start_with?("Bon")` | +| `end_with?` | Vérifie la fin | `text.end_with?("Ruby")` | +| `match?` | Teste une expression régulière | `text.match?(/Ruby/)` | + +### Transformer + +| Méthode | Utilité | Exemple | +|---|---|---| +| `upcase` | Met en majuscules | `text.upcase` | +| `downcase` | Met en minuscules | `text.downcase` | +| `capitalize` | Met la première lettre en majuscule | `text.capitalize` | +| `strip` | Supprime les espaces aux extrémités | `" Ruby ".strip` | +| `reverse` | Inverse la chaîne | `"Ruby".reverse` | +| `sub` | Remplace la première occurrence | `"test test".sub("test", "Ruby")` | +| `gsub` | Remplace toutes les occurrences | `"a-a-a".gsub("-", "_")` | + +### Découper + +| Méthode | Utilité | Exemple | +|---|---|---| +| `split` | Découpe en tableau | `"a,b,c".split(",")` | +| `chars` | Retourne un tableau de caractères | `"Ruby".chars` | +| `lines` | Retourne un tableau de lignes | `"a\nb".lines` | + +### Convertir + +| Méthode | Utilité | Exemple | +|---|---|---| +| `to_i` | Convertit en entier | `"42".to_i` | +| `to_f` | Convertit en nombre décimal | `"3.14".to_f` | +| `to_sym` | Convertit en symbole | `"name".to_sym` | + +--- + +## Integer + +```ruby +number = 42 +``` + +### Tester + +| Méthode | Utilité | Exemple | +|---|---|---| +| `even?` | Nombre pair | `42.even?` | +| `odd?` | Nombre impair | `7.odd?` | +| `zero?` | Égal à zéro | `0.zero?` | +| `positive?` | Strictement positif | `5.positive?` | +| `negative?` | Strictement négatif | `(-5).negative?` | + +### Manipuler + +| Méthode | Utilité | Exemple | +|---|---|---| +| `abs` | Valeur absolue | `(-5).abs` | +| `digits` | Retourne les chiffres en ordre inverse | `123.digits # => [3, 2, 1]` | + +### Répéter + +```ruby +3.times do + puts "Ruby" +end +``` + +`times` est particulièrement utile pour effectuer une action un nombre précis de fois. + +### Convertir + +| Méthode | Utilité | Exemple | +|---|---|---| +| `to_s` | Convertit en chaîne | `42.to_s` | +| `to_f` | Convertit en nombre décimal | `42.to_f` | + +--- + +## Float + +```ruby +number = 3.14159 +``` + +| Méthode | Utilité | Exemple | +|---|---|---| +| `round` | Arrondit | `3.14159.round(2) # => 3.14` | +| `floor` | Arrondit vers le bas | `3.9.floor # => 3` | +| `ceil` | Arrondit vers le haut | `3.1.ceil # => 4` | +| `to_i` | Convertit en entier | `3.9.to_i # => 3` | + +--- + +## Array + +```ruby +numbers = [1, 2, 3] +``` + +### Informations + +| Méthode | Utilité | Exemple | +|---|---|---| +| `length` / `size` | Nombre d'éléments | `numbers.length` | +| `empty?` | Vérifie si le tableau est vide | `numbers.empty?` | +| `include?` | Vérifie la présence d'une valeur | `numbers.include?(2)` | +| `index` | Position d'un élément | `numbers.index(2)` | + +### Accéder aux éléments + +| Méthode | Utilité | Exemple | +|---|---|---| +| `[]` | Accède à un élément | `numbers[0]` | +| `first` | Premier élément | `numbers.first` | +| `last` | Dernier élément | `numbers.last` | + +Les indices commencent à `0`. + +```ruby +numbers[0] +# => 1 +``` + +Les intervalles permettent d'extraire plusieurs éléments : + +```ruby +numbers[1..] +# => [2, 3] +``` + +### Ajouter et retirer + +| Méthode | Utilité | Exemple | +|---|---|---| +| `<<` | Ajoute à la fin | `numbers << 4` | +| `push` | Ajoute à la fin | `numbers.push(4)` | +| `pop` | Retire et retourne le dernier | `numbers.pop` | +| `unshift` | Ajoute au début | `numbers.unshift(0)` | +| `shift` | Retire et retourne le premier | `numbers.shift` | +| `delete` | Supprime les éléments égaux à une valeur | `numbers.delete(2)` | + +### Transformer + +| Méthode | Utilité | Exemple | +|---|---|---| +| `reverse` | Inverse le tableau | `numbers.reverse` | +| `sort` | Trie | `[3, 1, 2].sort` | +| `uniq` | Supprime les doublons | `[1, 1, 2].uniq` | +| `compact` | Supprime les `nil` | `[1, nil, 2].compact` | +| `flatten` | Aplatit les tableaux imbriqués | `[[1, 2], [3]].flatten` | +| `join` | Transforme en chaîne | `[1, 2, 3].join("-")` | +| `shuffle` | Mélange | `numbers.shuffle` | +| `sample` | Prend un élément au hasard | `numbers.sample` | + +### Combinaisons + +```ruby +[1, 2, 3].combination(2).to_a +# => [[1, 2], [1, 3], [2, 3]] +``` + +`combination` est utile lorsque l'ordre des éléments n'a pas d'importance. + +--- + +## Hash + +```ruby +person = { + name: "Alice", + age: 30 +} +``` + +### Accéder aux valeurs + +```ruby +person[:name] +# => "Alice" +``` + +| Méthode | Utilité | Exemple | +|---|---|---| +| `[]` | Lit une valeur | `person[:name]` | +| `[]=` | Ajoute ou modifie une valeur | `person[:age] = 31` | +| `fetch` | Lit une clé et signale son absence | `person.fetch(:name)` | +| `dig` | Cherche dans des structures imbriquées | `data.dig(:user, :name)` | + +### Informations + +| Méthode | Utilité | Exemple | +|---|---|---| +| `keys` | Retourne les clés | `person.keys` | +| `values` | Retourne les valeurs | `person.values` | +| `key?` | Vérifie la présence d'une clé | `person.key?(:name)` | +| `value?` | Vérifie la présence d'une valeur | `person.value?("Alice")` | +| `empty?` | Vérifie si le Hash est vide | `person.empty?` | +| `size` | Nombre de paires clé-valeur | `person.size` | + +### Modifier + +| Méthode | Utilité | Exemple | +|---|---|---| +| `delete` | Supprime une clé | `person.delete(:age)` | +| `merge` | Retourne un nouveau Hash fusionné | `person.merge(city: "Paris")` | + +--- + +## Enumerable + +`Enumerable` fournit une grande partie des méthodes utilisées pour parcourir, transformer et interroger des collections. + +`Array`, `Hash` et `Range` utilisent notamment ce module. + +```ruby +numbers = [1, 2, 3, 4] +``` + +### Parcourir + +#### `each` + +Effectue une action pour chaque élément. + +```ruby +numbers.each do |number| + puts number +end +``` + +#### `each_with_index` + +Fournit l'élément et sa position. + +```ruby +numbers.each_with_index do |number, index| + puts "#{index}: #{number}" +end +``` + +### Transformer : `map` + +Crée un nouveau tableau en transformant chaque élément. + +```ruby +numbers.map { |number| number * 2 } +# => [2, 4, 6, 8] +``` + +À retenir : + +> `map` = transformer chaque élément. + +### Filtrer : `select` + +Conserve les éléments qui respectent une condition. + +```ruby +numbers.select(&:even?) +# => [2, 4] +``` + +À retenir : + +> `select` = garder certains éléments. + +### Rejeter : `reject` + +Inverse de `select`. + +```ruby +numbers.reject(&:even?) +# => [1, 3] +``` + +### Trouver : `find` + +Retourne le premier élément correspondant. + +```ruby +numbers.find { |number| number > 2 } +# => 3 +``` + +### Tester une collection + +#### `any?` + +Au moins un élément correspond-il ? + +```ruby +numbers.any?(&:even?) +# => true +``` + +#### `all?` + +Tous les éléments correspondent-ils ? + +```ruby +numbers.all?(&:positive?) +# => true +``` + +#### `none?` + +Aucun élément ne correspond-il ? + +```ruby +numbers.none?(&:negative?) +# => true +``` + +### Compter : `count` + +```ruby +numbers.count(&:even?) +# => 2 +``` + +### Additionner : `sum` + +```ruby +numbers.sum +# => 10 +``` + +### Minimum et maximum + +```ruby +numbers.min +numbers.max +``` + +Pour choisir selon une propriété : + +```ruby +words = ["chat", "éléphant", "chien"] + +words.min_by(&:length) +# => "chat" + +words.max_by(&:length) +# => "éléphant" +``` + +### Trier selon un critère : `sort_by` + +```ruby +words.sort_by(&:length) +``` + +### Regrouper : `group_by` + +```ruby +words.group_by(&:length) +``` + +Retourne un `Hash` regroupant les éléments selon le résultat du bloc. + +### Parcourir par groupes + +#### `each_cons` + +Groupes successifs qui se chevauchent : + +```ruby +[1, 2, 3, 4].each_cons(2).to_a +# => [[1, 2], [2, 3], [3, 4]] +``` + +#### `each_slice` + +Groupes successifs qui ne se chevauchent pas : + +```ruby +[1, 2, 3, 4].each_slice(2).to_a +# => [[1, 2], [3, 4]] +``` + +### Accumuler : `reduce` / `inject` + +```ruby +[1, 2, 3, 4].reduce(0) do |total, number| + total + number +end + +# => 10 +``` + +Pour une simple addition, `sum` est généralement plus clair. + +--- + +## Range + +```ruby +range = 1..5 +``` + +### Parcourir + +```ruby +(1..5).each do |number| + puts number +end +``` + +### Tester + +```ruby +(1..5).include?(3) +# => true +``` + +### Convertir en tableau + +```ruby +(1..5).to_a +# => [1, 2, 3, 4, 5] +``` + +### Avancer par étapes + +```ruby +(0..10).step(2).to_a +# => [0, 2, 4, 6, 8, 10] +``` + +### `..` et `...` + +```ruby +1..5 +``` + +inclut `5`. + +```ruby +1...5 +``` + +n'inclut pas `5`. + +--- + +## Regexp + +Les expressions régulières permettent de rechercher un motif dans du texte. + +```ruby +text = "Ruby123" +``` + +### `match?` + +```ruby +text.match?(/\d+/) +# => true +``` + +Quelques motifs courants : + +| Motif | Signification | +|---|---| +| `\d` | chiffre | +| `\w` | caractère de mot | +| `\s` | espace | +| `.` | presque n'importe quel caractère | +| `+` | une ou plusieurs fois | +| `*` | zéro ou plusieurs fois | +| `?` | zéro ou une fois | +| `\A` | début de chaîne | +| `\z` | fin de chaîne | + +Exemple : + +```ruby +"123".match?(/\A\d+\z/) +# => true +``` + +--- + +## Object + +Ces méthodes sont utiles avec presque tous les objets Ruby. + +### `class` + +Retourne la classe de l'objet. + +```ruby +"Ruby".class +# => String + +42.class +# => Integer +``` + +Très utile pour comprendre ce que l'on manipule. + +### `nil?` + +```ruby +value.nil? +``` + +Teste si une valeur est `nil`. + +### `is_a?` + +```ruby +"Ruby".is_a?(String) +# => true +``` + +### `respond_to?` + +Vérifie qu'un objet répond à une méthode. + +```ruby +"Ruby".respond_to?(:upcase) +# => true +``` + +--- + +## Conversions courantes + +```ruby +42.to_s +"42".to_i +"3.14".to_f + +"Ruby".chars +"Ruby".to_sym + +(1..5).to_a + +["a", "b", "c"].join(", ") +``` + +Lorsque quelque chose semble impossible à manipuler directement, penser à la question : + +> **Est-ce que je dois d'abord convertir cet objet ?** + +--- + +## Choisir une méthode selon le besoin + +| Je veux… | Penser à… | +|---|---| +| parcourir tous les éléments | `each` | +| connaître également leur position | `each_with_index` | +| transformer chaque élément | `map` | +| garder certains éléments | `select` | +| éliminer certains éléments | `reject` | +| trouver le premier élément correspondant | `find` | +| savoir si au moins un correspond | `any?` | +| savoir si tous correspondent | `all?` | +| savoir si aucun ne correspond | `none?` | +| compter les éléments correspondants | `count` | +| additionner | `sum` | +| trouver le plus petit / grand | `min`, `max` | +| comparer selon une propriété | `min_by`, `max_by` | +| trier selon une propriété | `sort_by` | +| regrouper selon une propriété | `group_by` | +| parcourir avec les voisins | `each_cons` | +| parcourir par groupes séparés | `each_slice` | +| combiner des éléments | `combination` | +| répéter N fois | `times` | +| découper une chaîne | `split`, `chars` | +| chercher dans une chaîne | `include?`, `match?` | +| ajouter à un tableau | `<<`, `push` | +| retirer le dernier élément | `pop` | +| retirer le premier élément | `shift` | +| obtenir le type d'un objet | `class` | +| vérifier une méthode disponible | `respond_to?` | +| convertir un objet | `to_s`, `to_i`, `to_f`, `to_a` | + +--- + +## Méthodes avec `!` + +Certaines méthodes possèdent une version terminée par `!` : + +```ruby +numbers.sort +numbers.sort! +``` + +Dans ce type de paire, la méthode sans `!` retourne généralement un nouvel objet alors que la version avec `!` modifie directement le receveur. + +Exemple : + +```ruby +numbers = [3, 1, 2] + +sorted = numbers.sort + +numbers +# => [3, 1, 2] + +sorted +# => [1, 2, 3] +``` + +Avec : + +```ruby +numbers.sort! +``` + +`numbers` lui-même est modifié. + +Le `!` est une convention Ruby signalant une méthode plus dangereuse ou ayant des effets plus importants que sa version correspondante sans `!`. + +Il ne signifie pas systématiquement « modifie l'objet » et toutes les méthodes qui modifient un objet ne se terminent pas par `!`. + +--- + +## Réflexe devant un exercice + +Avant de chercher une méthode, identifier ce que l'on manipule : + +```ruby +object.class +``` + +Puis formuler l'opération recherchée : + +```text +Quel est mon objet ? + ↓ +String / Integer / Array / Hash… + ↓ +Qu'est-ce que je veux obtenir ? + ↓ +parcourir / transformer / filtrer / chercher / convertir… + ↓ +Quelle famille de méthodes correspond ? +``` + +Exemple : + +```ruby +number = 123 +``` + +Je veux parcourir ses chiffres. + +```text +Integer +↓ +je veux une collection de chiffres +↓ +conversion possible +↓ +to_s +↓ +String +↓ +chars +↓ +Array +↓ +each / map / each_with_index… +``` + +La bonne méthode n'est pas nécessairement disponible sur l'objet de départ : **la conversion vers un type plus adapté fait souvent partie de la solution**.