define_method: Comment créer dynamiquement des méthodes avec des arguments
Je veux créer un tas de méthodes pour une find_by fonctionnalité. Je ne veux pas écrire la même chose encore et encore si je veux utiliser la métaprogrammation.
Dis que je veux créer une méthode pour trouver par nom, d'accepter le nom comme argument. Comment aurais-je le faire? J'ai utilisé define_method dans le passé, mais je n'ai pas d'arguments en faveur de la méthode à suivre.
Voici mon (mauvais) approche
["name", "brand"].each do |attribute|
define_method("self.find_by_#{attribute}") do |attr_|
all.each do |prod|
return prod if prod.attr_ == attr_
end
end
end
Toute pensée? Merci à l'avance.
Être au courant si tout est un grand ensemble de données, ce qui pourrait provoquer des problèmes de performances. Aussi, j'espère sincèrement que c'est à l'extérieur des rails contexte rails implémente déjà
Remarque: cela permettra de définir deux méthodes nommées
Ce n'est pas les rails! tout simplement renvoie un tableau de
Je n'avais aucune idée à ce sujet, et je me demandais pourquoi le NoMethodError, depuis que j'ai eu une auto.quelque chose de méthode.
find_by_XXX
pour chaque attribut.Remarque: cela permettra de définir deux méthodes nommées
self.find_by_name
et self.find_by_brand
. Alors qu'il est possible de créer de telles méthodes, il est impossible d'appeler à l'aide de la méthode habituelle syntaxe d'appel, parce que .
n'est pas un caractère juridique à un identificateur. Est-il une raison particulière pour laquelle vous souhaitez définir une méthode illégale d'un nom?Ce n'est pas les rails! tout simplement renvoie un tableau de
Products
pour le système de gestion des stocks d'un magasin de Jouets. C'est pour le projet final pour le Ruby Nanodegree à Udacity.Je n'avais aucune idée à ce sujet, et je me demandais pourquoi le NoMethodError, depuis que j'ai eu une auto.quelque chose de méthode.
OriginalL'auteur Kostas Andrianos | 2016-07-06
Vous devez vous connecter pour publier un commentaire.
Si je comprends votre question correctement, vous voulez quelque chose comme ceci:
(Je suis en supposant que le
all
méthode retourne une Énumération.)Ci-dessus est plus ou moins équivalente à la définition des deux méthodes de la classe comme ceci:
class << self
et vu qu'il ouvre une classe et les changements de comportement, mais, pourquoi aurais-je besoin de le faire à l'intérieur de la classe elle-même?Vous avez besoin de le faire parce que vous voulez définir une méthode de classe. Sans cela,
define_method
définir une méthode d'instance, etdefine_method("self.foo")
comme dans votre exemple ne fonctionne pas.Merci beaucoup! Je vais regarder de plus afin d'être plus à l'aise avec la Métaprogrammation, mais pour l'instant, vous m'a beaucoup aidé! 🙂
Les plus idiomatiques moyen serait d'utiliser
define_singleton_method
.La distinction de la définition d'une méthode de classe vs une méthode d'instance est extrêmement important pour des raisons de performance. Merci pour mentionner que @Jordan
OriginalL'auteur Jordan Running
Si vous lisez les exemples ici http://apidock.com/ruby/Module/define_method, vous trouverez celui-ci:
est le même que
OriginalL'auteur Albin
Quand vous faites cela:
define_method("self.find_by_#{attribute}")
qui est incorrect. L'argument de define_method est un symbole d'un seul mot.
Permettez-moi de vous montrer quelques-unes de corriger le code, j'espère que ce sera clair:
Cela permettra de produire des méthodes de la classe pour
find_by_brand
etfind_by_name
.Noter que si vous êtes à la recherche dans la métaprogrammation, c'est un bon cas d'utilisation pour method_missing. voici un tutoriel à utiliser method_missing pour mettre en œuvre la même fonctionnalité que vous allez pour (
find_by_<x>
)find_by_XXX
est déjà défini. Aussidefine_method
peut accepter une Chaîne sans problème.method_missing
est quelque chose que je déteste. Il n'est pas facile de trouver des méthodes définies dans cette voie. A éviter si possible.convenu
OriginalL'auteur max pleaner