No sé por qué todo el mundo sugiere que deberías estar usando instance_methods
y include?
cuándo method_defined?
hace el trabajo.
class Test
def hello; end
end
Test.method_defined? :hello #=> true
NOTA
En caso de que venga a Ruby desde otro lenguaje OO O cree que eso method_defined
significa SOLO métodos que definió explícitamente con:
def my_method
end
entonces lee esto:
En Ruby, una propiedad (atributo) en su modelo es básicamente un método también. Por method_defined?
lo tanto , también devolverá verdadero para las propiedades, no solo los métodos.
Por ejemplo:
Dada una instancia de una clase que tiene un atributo String first_name
:
<instance>.first_name.class #=> String
<instance>.class.method_defined?(:first_name) #=> true
dado que first_name
es tanto un atributo como un método (y una cadena de tipo String).
String.instance_methods(false).include? :freeze
, el argumento falso puede decir exactamente si elfreeze
método está definido en la clase String o no. En este caso, devolverá falso porquefreeze
String hereda el método del módulo Kernel, peroString.method_defined? :freeze
siempre devolverá verdadero, lo que no puede ayudar mucho con tal propósito.method_defined?
debe usarse en la clase (pArray
. ej. ), pero está intentando usarlo en instancias (p[]
. ej. )Puedes usar
method_defined?
lo siguiente:Mucho más fácil, portátil y eficiente de lo que
instance_methods.include?
todos los demás parecen estar sugiriendo.Tenga en cuenta que no sabrá si una clase responde dinámicamente a algunas llamadas con
method_missing
, por ejemplorespond_to?
, redefiniendo , o desde Ruby 1.9.2 definiendorespond_to_missing?
.fuente
instance.class.method_defined? :upcase
En realidad, esto no funciona tanto para objetos como para clases.
Esto hace:
Entonces, con la respuesta dada, esto funciona:
Pero esto no funciona:
Así que uso esto para clases y objetos:
Clases
Objetos:
fuente
La respuesta a " Dada una clase, vea si la instancia tiene método (Ruby) " es mejor. Aparentemente, Ruby tiene esto incorporado, y de alguna manera lo extrañé. Mi respuesta se deja como referencia, independientemente.
Las clases de Ruby responden a los métodos
instance_methods
ypublic_instance_methods
. En Ruby 1.8, el primero enumera todos los nombres de métodos de instancia en una matriz de cadenas, y el segundo lo restringe a métodos públicos. El segundo comportamiento es lo que probablemente desearía, ya que también serespond_to?
limita a los métodos públicos de forma predeterminada.Sin embargo, en Ruby 1.9, esos métodos devuelven matrices de símbolos.
Si planea hacer esto con frecuencia, es posible que desee ampliar
Module
para incluir un método de acceso directo. (Puede parecer extraño asignar esto a, enModule
lugar deClass
, pero dado que allí es dondeinstance_methods
viven los métodos, es mejor mantenerse en línea con ese patrón).Si desea admitir tanto Ruby 1.8 como Ruby 1.9, ese sería un lugar conveniente para agregar la lógica para buscar cadenas y símbolos también.
fuente
method_defined?
es mejor :)Tratar
Foo.instance_methods.include? :bar
fuente
No estoy seguro si esta es la mejor manera, pero siempre puedes hacer esto:
fuente
Creo que hay algo mal con
method_defined?
Rails. Puede ser inconsistente o algo así que, si usa Rails, es mejor usar algo deattribute_method?(attribute)
."la prueba de método_definido? en las clases ActiveRecord no funciona hasta una instanciación " es una pregunta sobre la inconsistencia.
fuente
Si está verificando si un objeto puede responder a una serie de métodos, podría hacer algo como:
Se
methods & something.methods
unirán las dos matrices en sus elementos comunes / coincidentes. something.methods incluye todos los métodos que está buscando, será igual a los métodos. Por ejemplo:entonces
En esta situación, querrá usar símbolos, porque cuando llama a .methods, devuelve una matriz de símbolos y, si lo usa
["my", "methods"]
, devolvería false.fuente
klass.instance_methods.include :method_name
o"method_name"
, dependiendo de la versión de Ruby, creo.fuente
¡Espero que esto te ayude!
fuente
En mi caso, trabajar con ruby 2.5.3 las siguientes oraciones han funcionado perfectamente:
Devolverá un valor booleano verdadero o falso.
fuente
Si bien
respond_to?
será verdadero solo para los métodos públicos, la verificación de la "definición de método" en una clase también puede pertenecer a métodos privados.En Ruby v2.0 +, la comprobación de conjuntos públicos y privados se puede lograr con
fuente