Wir hatten kürzlich ein Problem, bei dem nach einer Reihe von Commits ein Backend-Prozess nicht ausgeführt werden konnte. Jetzt waren wir gute kleine Jungen und Mädchen und rannten rake test
nach jedem Check-in, aber aufgrund einiger Kuriositäten beim Laden der Rails-Bibliothek trat dies nur auf, wenn wir es direkt von Mongrel im Produktionsmodus aus liefen.
Ich habe den Fehler aufgespürt und es lag daran, dass ein neues Rails-Juwel eine Methode in der String-Klasse so überschrieb, dass eine enge Verwendung im Rails-Laufzeitcode gebrochen wurde.
Wie auch immer, kurz gesagt, gibt es zur Laufzeit eine Möglichkeit, Ruby zu fragen, wo eine Methode definiert wurde? So etwas whereami( :foo )
kehrt zurück /path/to/some/file.rb line #45
? In diesem Fall wäre es nicht hilfreich, mir mitzuteilen, dass es in der Klasse String definiert wurde, da es von einer Bibliothek überladen wurde.
Ich kann nicht garantieren, dass die Quelle in meinem Projekt lebt, daher 'def foo'
gibt mir das Greifen nach nicht unbedingt das, was ich brauche, ganz zu schweigen davon, ob ich viele habe def foo
. Manchmal weiß ich erst zur Laufzeit, welche ich möglicherweise verwende.
quelle
Antworten:
Dies ist sehr spät, aber hier erfahren Sie, wo eine Methode definiert ist:
http://gist.github.com/76951
Wenn Sie mit Ruby 1.9+ arbeiten, können Sie verwenden
source_location
Beachten Sie, dass dies nicht bei allen Funktionen funktioniert, z. B. bei nativem kompiliertem Code. Die Method-Klasse hat auch einige nette Funktionen, wie z. B. den Method # -Eigentümer, der die Datei zurückgibt, in der die Methode definiert ist.
BEARBEITEN: Siehe auch die
__file__
und__line__
und Hinweise für REE in der anderen Antwort, sie sind auch praktisch. - wgquelle
owner
Methode2.method(:crime)
?Fixnum
method_missing
. Wenn Sie also ein Modul oder eine Vorfahrenklasse mit einemclass_eval
oderdefine_method
innerhalb von habenmethod_missing
, funktioniert diese Methode nicht.Sie können tatsächlich ein bisschen weiter gehen als die obige Lösung. Für Ruby 1.8 Enterprise Edition gibt es die
__file__
und__line__
-Methoden fürMethod
Instanzen:Für Ruby 1.9 und höher gibt es
source_location
(danke Jonathan!):quelle
__file__
und__line__
für jedeMethod
Klasseninstanz, zmethod(:method).__file__
.m.__file__
undm.__line__
wurden durch ersetztm.source_location
.Ich komme zu spät zu diesem Thread und bin überrascht, dass niemand erwähnt hat
Method#owner
.quelle
Method#parameters
.Kopieren meiner Antwort von einer neueren ähnlichen Frage , die diesem Problem neue Informationen hinzufügt.
Ruby 1.9 hat eine Methode namens source_location :
Dies wurde von diesem Juwel auf 1.8.7 zurückportiert :
Sie können also die Methode anfordern:
Und dann fragen Sie nach der
source_location
Methode:Dies gibt ein Array mit Dateiname und Zeilennummer zurück. ZB für
ActiveRecord::Base#validates
diese Rückkehr:Für Klassen und Module bietet Ruby keine integrierte Unterstützung, aber es gibt eine hervorragende Übersicht, die darauf aufbaut,
source_location
eine Datei für eine bestimmte Methode oder eine erste Datei für eine Klasse zurückzugeben, wenn keine Methode angegeben wurde:In Aktion:
Auf Macs mit installiertem TextMate wird dadurch auch der Editor am angegebenen Speicherort angezeigt.
quelle
Dies kann helfen, aber Sie müssten es selbst codieren. Aus dem Blog eingefügt:
http://scie.nti.st/2008/9/17/making-methods-immutable-in-ruby
quelle
Wenn Sie die Methode zum Absturz bringen können, erhalten Sie eine Rückverfolgung, die Ihnen genau sagt, wo sie sich befindet.
Wenn Sie es nicht zum Absturz bringen können, können Sie leider nicht herausfinden, wo es definiert wurde. Wenn Sie versuchen, mit der Methode einen Affen zu erstellen, indem Sie sie überschreiben oder überschreiben, kommt es zu einem Absturz Ihrer überschriebenen oder überschriebenen Methode, der keinen Nutzen bringt.
Nützliche Methoden zum Absturz von Methoden:
nil
wo es verboten ist - die meiste Zeit wird die Methode eineArgumentError
oder die allgegenwärtigeNoMethodError
Klasse auf Null setzen.quelle
require 'ruby-debug'; debugger
in Ihren Code einfügen , wo Sie vorbeischauen möchten.Vielleicht
#source_location
kann das helfen, herauszufinden, woher die Methode kommt.Ex:
Rückkehr
ODER
Rückkehr
quelle
Sehr späte Antwort :) Aber frühere Antworten haben mir nicht geholfen
quelle
nil
?nil
.»Möglicherweise können Sie Folgendes tun:
foo_finder.rb:
Stellen Sie dann sicher, dass foo_finder zuerst mit etwas wie geladen wird
(Ich habe nur mit Schienen herumgespielt, daher weiß ich es nicht genau, aber ich stelle mir vor, dass es einen Weg gibt, es so zu starten.)
Dies zeigt Ihnen alle Neudefinitionen von String # foo. Mit ein wenig Metaprogrammierung können Sie es für jede gewünschte Funktion verallgemeinern. Es muss jedoch VOR der Datei geladen werden, die die Neudefinition tatsächlich durchführt.
quelle
Mit können Sie jederzeit einen Rückblick darauf erhalten, wo Sie sich befinden
caller()
.quelle