2014-03-07 16 views
12

Ich bin in einer Situation zu finden, die gem na foo_bar, die ich geschrieben habe, und die ich wie folgt verwenden:eines Moduls Standort

require 'foo_bar' 
include FooBar 

suddendly, eine Konstante Baz erschienen:

defined? Baz #=> :constant 
Baz.class #=> Module 

Ich habe vergessen, wo ich Baz definiert habe. Wenn es irgendwelche Instanzmethoden hatte, könnte ich #source_location Methode verwenden, um die Datei zu finden, wo ich Baz definierte. Aber es hat keine:

Baz.instance_methods #=> [] 

Wie finde ich, in der Datei (oder wo) ein Modul, das in meiner Top-Namespace tauchte definiert?

Zusätzliche addmission und Befund: Die Konstante ich rede ist Net, und sein Aussehen ist nicht gebunden an include FooBar, sondern auf eine andere Linie, require meiner gem sy (http://gihub.com/boris-s/sy), die Sie durch gem install sy installieren können. Durch Treten des Edelsteins (https://github.com/boris-s/sy/blob/master/lib/sy.rb) habe ich festgestellt, dass keine der erforderlichen Zeilen oder die oberen Zeilen bis zur module SY Zeile nicht Net aussehen. Die module SY Definition tut dies.

Außerdem, fand ich die pragmatische Antwort NetNet wie in Net::HTTP ist. Die Autoren nahmen nicht an, dass jemand mit anderen Arten von Netzen als mit Internet arbeiten würde, und ich dachte nicht an Net::HTTP, weil ich mit Petrinetzen arbeitete und meine eigenen Net Klassen definierte. Obwohl ich mein praktisches Problem gelöst habe, ist es immer noch interessant, die allgemeine Antwort zu finden, Quellen von Modulen zu finden.

+2

Ich weiß nicht, die Antwort noch nicht, aber die gute Nachricht ist, wenn Sie MRI Ruby-verwenden, wird der Quellort definitiv gespeichert. Die Definition der Funktion 'rb_const_set' die folgenden Linien enthält: ' ce = ALLOC (rb_const_entry_t); '' MEMZERO (CE, rb_const_entry_t, 1); '' CE-> Flag = Sichtbarkeit; '' CE- > line = rb_sourceline(); ' –

+2

Es scheint, dass es gespeichert wird, so dass es in der Warnung" vorherige Definition von% s war hier "zurück gerufen werden kann, aber ich habe Mühe, diese Warnung zu bekommen, um jetzt tatsächlich zu erscheinen . Ich bekomme nur immer '' bereits initialisierte Konstante% s ''. –

+0

Schöne Frage, lass es mich auch versuchen. –

Antwort

1

eine Datei Angenommen wird geladen Sie tun können:

$LOADED_FEATURES.select { |file| File.read(file).include?('module Foo') rescue false } 
+1

Ich baute ein Juwel für Ihre Bequemlichkeit. http://rubygems.org/gems/modloc –

+0

Eine feine pragmatische Lösung, ich bin gezwungen, es zu akzeptieren =). Sie haben mir ein gutes Beispiel für die Verwendung der globalen Variablen $ LOADED_FEATURES beigebracht. –

+0

Das Schmuckstück deckt einige andere Anwendungsfälle wie den Namensabstand ab. Es ist nicht zu komplex, also wenn dieser Einzeiler nicht Ihren Bedürfnissen entspricht, sehen Sie sich den Inhalt des Edelsteins an. https://github.com/jwaldrop/modloc/blob/master/lib/modloc/core_ext/module.rb –

-1

Dies kann den Trick (Rubin 1.9+) tun:

method(:Baz).source_location

Beispiel:

2.1.0 :001 > require 'json' 
=> true 
2.1.0 :002 > JSON.class 
=> Module 
2.1.0 :003 > method(:JSON).source_location 
=> ["/usr/local/Cellar/ruby/2.1.1/lib/ruby/2.1.0/json/common.rb", 466] 

Ältere Versionen von Ruby andere Möglichkeiten hatte wie Baz.__file__ aber wurden in 1,9 mit Quellpfad ersetzt +. Sie können auch ein Gem, das hilft, wie method_locator (https://github.com/ryanlecompte/method_locator) untersuchen.

+1

Das funktioniert, weil 'JSON' hier eine Methode ist. Die Frage lautete, wo sich ein Modul befindet, wenn keine Instanzmethoden vorhanden sind. – Kashyap

+0

Glücklicherweise hat das Modul in meinem Fall Konstanten mit Instanzmethoden, also weiß ich, wo es herkommt, aber ich habe keine Ahnung, wo oder wie es definiert ist. –

Verwandte Themen