Ruby Programming

Maîtriser `call()` et `send()` en Ruby

Spread the love

Table des matières

  1. Qu’est-ce que call() en Ruby ?
  2. Qu’est-ce que send() en Ruby ?
  3. Applications pratiques de call() et send()
  4. Conclusion
  5. FAQ

Qu’est-ce que call() en Ruby ?

La méthode call(), également connue sous le nom de « méthode d’appel » ou « méthode appelable », permet d’appeler une méthode sur un objet en utilisant l’opérateur d’appel de méthode (). Cela transforme les objets en entités appelables, semblables aux fonctions ou procédures. Toute classe peut définir une méthode call(), rendant ses instances appelables.


class Adder
  def initialize(x)
    @x = x
  end

  def call(y)
    @x + y
  end
end

adder = Adder.new(5)
result = adder.call(3)  # result vaudra 8
result = adder.(3)      # Équivalent utilisant l'opérateur d'appel de méthode
puts result             # Sortie : 8

call() est inestimable pour créer des fonctions personnalisées ou des blocs de code qui peuvent être passés et exécutés plus tard. C’est une pierre angulaire des capacités de programmation fonctionnelle de Ruby.

Qu’est-ce que send() en Ruby ?

La méthode send() appelle dynamiquement une méthode sur un objet, en acceptant le nom de la méthode sous forme de chaîne de caractères ou de symbole. Cela permet une manipulation en temps d’exécution des objets et de leurs méthodes.


class Greeter
  def hello(name)
    "Bonjour, #{name} !"
  end

  def goodbye(name)
    "Au revoir, #{name} !"
  end
end

greeter = Greeter.new
message = greeter.send(:hello, "World")  # message vaudra "Bonjour, World !"
puts message

message = greeter.send("goodbye", "World") # message vaudra "Au revoir, World !"
puts message

Le nom de la méthode (`:hello` ou ` »goodbye »`) est passé en argument à send(), offrant une invocation de méthode flexible, même en fonction de conditions dynamiques. Cependant, la prudence est de mise lors de l’utilisation de send() avec des données non fiables pour éviter les failles de sécurité.

Applications pratiques de call() et send()

call() et send() offrent des avantages distincts :

  • call() : Idéal pour créer des objets appelables, implémenter des stratégies (par exemple, différents algorithmes de tri) et travailler avec des concepts de programmation fonctionnelle comme les lambdas et les procs. Il fournit une syntaxe plus propre et plus lisible que send() pour les méthodes prédéfinies.
  • send() : Utile pour la métaprogrammation, l’envoi dynamique de méthodes en fonction de conditions d’exécution et la création d’API flexibles. Il est particulièrement utile lorsque le nom de la méthode est inconnu au moment de la compilation. Cependant, une utilisation excessive peut réduire la lisibilité et la maintenabilité du code.

Exemple : Pattern Stratégie avec call()


class SortStrategy
  def call(array)
    raise NotImplementedError, "Les sous-classes doivent implémenter la méthode call"
  end
end

class BubbleSort < SortStrategy
  def call(array)
    # Implémentation du tri à bulles... (Implémentation omise pour des raisons de concision)
  end
end

class QuickSort < SortStrategy
  def call(array)
    # Implémentation du tri rapide... (Implémentation omise pour des raisons de concision)
  end
end

sorter = BubbleSort.new
sorted_array = sorter.call([3, 1, 4, 1, 5, 9, 2, 6])

Ceci démontre comment call() implémente élégamment le pattern Stratégie.

Conclusion

call() et send() sont des outils Ruby puissants. call() offre une approche fonctionnelle propre pour créer des objets appelables, tandis que send() fournit une invocation de méthode dynamique. Comprendre leurs forces et leurs faiblesses permet aux développeurs de choisir la méthode appropriée pour chaque tâche, améliorant ainsi la flexibilité et la maintenabilité du code. Utilisez send() avec prudence, en particulier avec des données non fiables, pour atténuer les risques de sécurité.

FAQ

  • Q : Quelles sont les implications de sécurité de l’utilisation de send() ?
    R : L’utilisation de send() avec des données non fiables peut permettre l’exécution malveillante de méthodes arbitraires, créant ainsi des vulnérabilités. Nettoyez et validez toujours les données avant d’utiliser send().
  • Q : Puis-je utiliser call() avec n’importe quelle méthode ?
    R : Non, call() est spécifiquement pour les méthodes nommées call().
  • Q : send() est-il plus rapide que l’appel direct d’une méthode ?
    R : Non, send() implique une recherche, ce qui le rend plus lent. Utilisez-le uniquement lorsque l’invocation dynamique est nécessaire.
  • Q : Quelle est la différence entre send et public_send ?
    R : public_send appelle uniquement les méthodes publiques, améliorant la sécurité en empêchant l’accès aux méthodes privées/protégées. send peut appeler des méthodes de toute visibilité.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *