Je ne sais pas pourquoi tout le monde suggère que vous devriez utiliser instance_methods
et include?
quand method_defined?
fait le travail.
class Test
def hello; end
end
Test.method_defined? :hello #=> true
REMARQUE
Dans le cas où vous venez vers Ruby à partir d'un autre langage OO OU vous pensez que cela method_defined
signifie UNIQUEMENT des méthodes que vous avez définies explicitement avec:
def my_method
end
puis lisez ceci:
Dans Ruby, une propriété (attribut) sur votre modèle est également une méthode. Donc, method_defined?
cela retournera également true pour les propriétés, pas seulement pour les méthodes.
Par exemple:
Étant donné une instance d'une classe qui a un attribut String first_name
:
<instance>.first_name.class #=> String
<instance>.class.method_defined?(:first_name) #=> true
puisqu'il first_name
s'agit à la fois d'un attribut et d'une méthode (et d'une chaîne de type String).
String.instance_methods(false).include? :freeze
le faux argument peut indiquer exactement si lafreeze
méthode est définie dans la classe String ou non. Dans ce cas, il retournera false car lafreeze
méthode est héritée du module du noyau par String, maisString.method_defined? :freeze
retournera toujours true, ce qui ne peut pas aider beaucoup à cet effet.method_defined?
doit être utilisé sur la classe (par exempleArray
), mais vous essayez de l'utiliser sur des instances (par exemple[]
)Vous pouvez utiliser
method_defined?
comme suit:Beaucoup plus facile, portable et efficace que
instance_methods.include?
tout le monde semble le suggérer.Gardez à l'esprit que vous ne saurez pas si une classe répond dynamiquement à certains appels avec
method_missing
, par exemple en redéfinissantrespond_to?
, ou depuis Ruby 1.9.2 en définissantrespond_to_missing?
.la source
instance.class.method_defined? :upcase
En fait, cela ne fonctionne pas pour les objets et les classes.
Cela fait:
Donc, avec la réponse donnée, cela fonctionne:
Mais cela ne fonctionne PAS:
J'utilise donc ceci pour les classes et les objets:
Des classes:
Objets:
la source
La réponse à " Étant donné une classe, voyez si l'instance a une méthode (Ruby) " est meilleure. Apparemment, Ruby a cette fonction intégrée, et je l'ai ratée. Ma réponse est laissée pour référence, peu importe.
Les classes Ruby répondent aux méthodes
instance_methods
etpublic_instance_methods
. Dans Ruby 1.8, le premier répertorie tous les noms de méthode d'instance dans un tableau de chaînes et le second le restreint aux méthodes publiques. Le deuxième comportement est celui que vous souhaiteriez le plus, car il serespond_to?
limite également aux méthodes publiques par défaut.Dans Ruby 1.9, cependant, ces méthodes renvoient des tableaux de symboles.
Si vous prévoyez de le faire souvent, vous souhaiterez peut-être étendre
Module
pour inclure une méthode de raccourci. (Il peut sembler étrange d'affecter cela àModule
au lieu deClass
, mais puisque c'est là que vivent lesinstance_methods
méthodes, il est préférable de rester en ligne avec ce modèle.)Si vous souhaitez prendre en charge Ruby 1.8 et Ruby 1.9, ce serait un endroit pratique pour ajouter la logique de recherche de chaînes et de symboles.
la source
method_defined?
c'est mieux :)Essayer
Foo.instance_methods.include? :bar
la source
Je ne sais pas si c'est la meilleure façon, mais vous pouvez toujours le faire:
la source
Je pense qu'il y a un problème avec
method_defined?
Rails. Cela peut être incohérent ou quelque chose, donc si vous utilisez Rails, il vaut mieux utiliser quelque chose deattribute_method?(attribute)
."Le test de method_defined? sur les classes ActiveRecord ne fonctionne pas tant qu'une instanciation " est une question sur l'incohérence.
la source
Si vous vérifiez si un objet peut répondre à une série de méthodes, vous pouvez faire quelque chose comme:
le
methods & something.methods
joindra les deux tableaux sur leurs éléments communs / correspondants. Quelque chose.methods inclut toutes les méthodes que vous recherchez, cela égalera les méthodes. Par exemple:alors
Dans cette situation, vous souhaitez utiliser des symboles, car lorsque vous appelez .methods, il renvoie un tableau de symboles et si vous l'utilisez
["my", "methods"]
, il renvoie false.la source
klass.instance_methods.include :method_name
ou"method_name"
, selon la version Ruby je pense.la source
J'espère que cela vous aide!
la source
Sur mon cas de travail avec ruby 2.5.3, les phrases suivantes ont parfaitement fonctionné:
Il renverra une valeur booléenne true ou false.
la source
Bien que
respond_to?
renvoie true uniquement pour les méthodes publiques, la vérification de la "définition de méthode" sur une classe peut également concerner des méthodes privées.Sur Ruby v2.0 +, la vérification des ensembles publics et privés peut être réalisée avec
la source