Não sei por que todo mundo está sugerindo que você deveria usar instance_methods
e include?
quando method_defined?
faz o trabalho.
class Test
def hello; end
end
Test.method_defined? :hello #=> true
NOTA
Caso você esteja vindo para Ruby de outra linguagem OO OU você acha que method_defined
significa APENAS métodos que você definiu explicitamente com:
def my_method
end
então leia isto:
No Ruby, uma propriedade (atributo) no seu modelo também é basicamente um método. Então method_defined?
, também retornará true para propriedades, não apenas métodos.
Por exemplo:
Dada uma instância de uma classe que possui um atributo String first_name
:
<instance>.first_name.class #=> String
<instance>.class.method_defined?(:first_name) #=> true
uma vez que first_name
é um atributo e um método (e uma sequência do tipo String).
String.instance_methods(false).include? :freeze
, o argumento false pode dizer exatamente se ofreeze
método está definido na classe String ou não. Nesse caso, ele retornará false porque ofreeze
método é herdado do módulo Kernel por String, masString.method_defined? :freeze
sempre retornará true, o que não pode ajudar muito com esse objetivo.method_defined?
deve ser utilizado na classe (por exemploArray
), mas você está tentando usá-lo em casos (por exemplo[]
)Você pode usar da
method_defined?
seguinte maneira:Muito mais fácil, portátil e eficiente do que
instance_methods.include?
todo mundo parece sugerir.Lembre-se de que você não saberá se uma classe responde dinamicamente a algumas chamadas com
method_missing
, por exemplo, redefinindorespond_to?
ou desde o Ruby 1.9.2, definindorespond_to_missing?
.fonte
instance.class.method_defined? :upcase
Na verdade, isso não funciona para objetos e classes.
Isto faz:
Então, com a resposta dada, isso funciona:
Mas isso NÃO funciona:
Então, eu uso isso para classes e objetos:
Aulas:
Objetos:
fonte
A resposta para " Dada uma classe, veja se a instância possui o método (Ruby) " é melhor. Aparentemente, Ruby tem isso embutido, e de alguma forma eu perdi. Minha resposta é deixada para referência, independentemente.
As classes Ruby respondem aos métodos
instance_methods
epublic_instance_methods
. No Ruby 1.8, o primeiro lista todos os nomes de métodos de instância em uma matriz de seqüências de caracteres, e o segundo o restringe a métodos públicos. O segundo comportamento é o que você provavelmente desejaria, uma vez que também serespond_to?
restringe a métodos públicos.No Ruby 1.9, no entanto, esses métodos retornam matrizes de símbolos.
Se você planeja fazer isso com frequência, convém estender
Module
para incluir um método de atalho. (Pode parecer estranho atribuir isso aoModule
invés deClass
, mas como é onde osinstance_methods
métodos vivem, é melhor manter-se alinhado com esse padrão.)Se você deseja dar suporte ao Ruby 1.8 e ao Ruby 1.9, esse seria um local conveniente para adicionar a lógica para procurar por seqüências de caracteres e símbolos.
fonte
method_defined?
é melhor :) #Experimentar
Foo.instance_methods.include? :bar
fonte
Não tenho certeza se essa é a melhor maneira, mas você sempre pode fazer isso:
fonte
Eu acho que há algo errado com o
method_defined?
Rails. Pode ser inconsistente ou algo assim, portanto, se você usa o Rails, é melhor usar algo deattribute_method?(attribute)
." testar métodos_definidos? nas classes ActiveRecord não funciona até uma instanciação " é uma pergunta sobre a inconsistência.
fonte
Se você estiver verificando se um objeto pode responder a uma série de métodos, faça algo como:
o
methods & something.methods
unirá as duas matrizes em seus elementos comuns / correspondentes. something.methods inclui todos os métodos que você está verificando, serão iguais. Por exemplo:tão
Nessa situação, você desejaria usar símbolos, porque quando você chama .methods, ele retorna uma matriz de símbolos e, se você o usou
["my", "methods"]
, retornaria false.fonte
klass.instance_methods.include :method_name
ou"method_name"
, dependendo da versão do Ruby, eu acho.fonte
Espero que isso ajude você!
fonte
No meu caso, trabalhando com o ruby 2.5.3, as seguintes frases funcionaram perfeitamente:
Ele retornará um valor booleano verdadeiro ou falso.
fonte
Embora
respond_to?
retorne true somente para métodos públicos, a verificação de "definição de método" em uma classe também pode pertencer a métodos privados.No Ruby v2.0 +, a verificação de conjuntos públicos e privados pode ser obtida com
fonte