Ich weiß nicht, warum alle vorschlagen, dass Sie verwenden sollten instance_methods
und include?
wann method_defined?
der Job erledigt wird.
class Test
def hello; end
end
Test.method_defined? :hello #=> true
HINWEIS
Wenn Sie aus einer anderen OO-Sprache zu Ruby kommen oder der Meinung sind, dass method_defined
dies NUR Methoden bedeutet, die Sie explizit definiert haben mit:
def my_method
end
dann lies das:
In Ruby ist eine Eigenschaft (ein Attribut) in Ihrem Modell im Grunde auch eine Methode. Dies method_defined?
gilt auch für Eigenschaften, nicht nur für Methoden.
Beispielsweise:
Bei einer Instanz einer Klasse mit einem String-Attribut first_name
:
<instance>.first_name.class #=> String
<instance>.class.method_defined?(:first_name) #=> true
da first_name
ist sowohl ein Attribut als auch eine Methode (und eine Zeichenfolge vom Typ Zeichenfolge).
String.instance_methods(false).include? :freeze
kann das falsche Argument genau sagen, ob diefreeze
Methode in der String-Klasse definiert ist oder nicht. In diesem Fall wird false zurückgegeben, da diefreeze
Methode von String vom Kernel-Modul geerbt wird, aberString.method_defined? :freeze
immer true zurückgegeben, was bei einem solchen Zweck nicht viel helfen kann.method_defined?
muss für die Klasse verwendet werden (z. B.Array
), aber Sie versuchen, es für Instanzen zu verwenden (z. B.[]
)Sie können
method_defined?
wie folgt verwenden:Viel einfacher, tragbarer und effizienter als die
instance_methods.include?
alle anderen vermuten.Denken Sie daran, dass Sie nicht wissen, ob eine Klasse dynamisch auf einige Aufrufe reagiert
method_missing
, z. B. durch Neudefinitionrespond_to?
oder seit Ruby 1.9.2 durch Definierenrespond_to_missing?
.quelle
instance.class.method_defined? :upcase
Tatsächlich funktioniert dies nicht für Objekte und Klassen.
Das macht:
Mit der gegebenen Antwort funktioniert dies also:
Das funktioniert aber NICHT:
Also benutze ich dies sowohl für Klassen als auch für Objekte:
Klassen:
Objekte:
quelle
Die Antwort auf " Bei einer gegebenen Klasse prüfen, ob die Instanz eine Methode (Ruby) hat " ist besser. Anscheinend hat Ruby dieses eingebaut und ich habe es irgendwie verpasst. Meine Antwort bleibt unabhängig davon als Referenz.
Ruby-Klassen reagieren auf die Methoden
instance_methods
undpublic_instance_methods
. In Ruby 1.8 listet der erste alle Instanzmethodennamen in einem Array von Zeichenfolgen auf und der zweite beschränkt ihn auf öffentliche Methoden. Das zweite Verhalten ist das, was Sie höchstwahrscheinlich wollen, da esrespond_to?
sich standardmäßig auch auf öffentliche Methoden beschränkt.In Ruby 1.9 geben diese Methoden jedoch Arrays von Symbolen zurück.
Wenn Sie dies häufig planen, möchten Sie möglicherweise
Module
eine Verknüpfungsmethode hinzufügen. (Es mag seltsam erscheinen, diesModule
stattdessen zuzuweisenClass
, aber da dort dieinstance_methods
Methoden leben, ist es am besten, sich an dieses Muster zu halten.)Wenn Sie sowohl Ruby 1.8 als auch Ruby 1.9 unterstützen möchten, ist dies ein praktischer Ort, um die Logik für die Suche nach Zeichenfolgen und Symbolen hinzuzufügen.
quelle
method_defined?
ist besser :)Versuchen
Foo.instance_methods.include? :bar
quelle
Ich bin mir nicht sicher, ob dies der beste Weg ist, aber Sie können dies immer tun:
quelle
Ich denke, mit
method_defined?
Rails stimmt etwas nicht . Es kann inkonsistent sein oder so. Wenn Sie also Rails verwenden, ist es besser, etwas von zu verwendenattribute_method?(attribute)
." Testen auf method_defined? für ActiveRecord-Klassen funktioniert erst nach einer Instanziierung " ist eine Frage zur Inkonsistenz.
quelle
Wenn Sie überprüfen, ob ein Objekt auf eine Reihe von Methoden reagieren kann, können Sie Folgendes tun:
Sie
methods & something.methods
verbinden die beiden Arrays mit ihren gemeinsamen / übereinstimmenden Elementen. Something.methods enthält alle Methoden, nach denen Sie suchen. Es entspricht den Methoden. Beispielsweise:so
In dieser Situation möchten Sie Symbole verwenden, da beim Aufrufen von .methods ein Array von Symbolen zurückgegeben wird und wenn Sie diese verwendet haben
["my", "methods"]
false zurückgegeben wird.quelle
klass.instance_methods.include :method_name
oder"method_name"
, abhängig von der Ruby-Version, denke ich.quelle
Hoffe das hilft dir!
quelle
In meinem Fall mit Ruby 2.5.3 haben die folgenden Sätze perfekt funktioniert:
Es wird ein boolescher Wert true oder false zurückgegeben.
quelle
Während
respond_to?
nur für öffentliche Methoden true zurückgegeben wird, kann die Überprüfung auf "Methodendefinition" für eine Klasse auch private Methoden betreffen.Unter Ruby v2.0 + können sowohl öffentliche als auch private Sets überprüft werden
quelle