2010-08-11 6 views
19

Gibt es eine Möglichkeit, ein Rubygem im Speicher "neu zu laden" oder "zu aktualisieren"? Da ich in Irb spiele, mag ich gelegentlich meine Edelstein-Dateien zu ändern, und wenn ich das gleiche Juwel benötige, wird es nicht in den Speicher aktualisiert und gibt die Ausgabe "falsch". Momentan muss ich den IRB verlassen, zurück in den IRB gehen und dann den Edelstein wieder anfordern, es muss einen besseren Weg geben ... was ist das?Reload Rubygem in IRB

+0

wenn ich diese Funktionalität in wo sollte es gehen? Rubygems? Akzeptiert diese Community generell neue Feature Pull-Anfragen? – Schneems

Antwort

17

Wie andere vorgeschlagen haben, können Sie Kernel # load verwenden. . Aber verschwenden Sie Ihre Zeit nicht zu finden, und jede Edelstein-Datei als alle Dateien laden, die erforderlich wurden in $ gespeichert“Mit diesem Wissen, hier ist ein Reload-irb Befehl:

def reload(require_regex) 
    $".grep(/^#{require_regex}/).each {|e| load(e) } 
end 

Zum Beispiel, wenn Sie die hirb Juwel in irb verwendet haben, würden Sie einfach nachladen mit:

>> reload 'hirb' 

Wenn aus welchem ​​Grund auch immer Last funktioniert nicht (es ist pickier über Dateierweiterungen als erforderlich ist), können Sie jede Datei neu erfordern von zuerst lösche seinen Eintrag in $ ". Mit diesem Hinweis würde der obige Befehl lauten:

def reload(require_regex) 
    $".grep(/^#{require_regex}/).each {|e| $".delete(e) && require(e) } 
end 

Wählen Sie, was für Sie funktioniert. Persönlich benutze ich Letzteres.

+0

Funktioniert das auch für Skripte aus dem Dateisystem? Es funktionierte nicht für meins ... und meine require-Anweisung sieht so aus: 'require' # {File.expand_path (__ FILE __)}/../ lib/query '' – picardo

+2

Es tut nicht, nein. Die Regex ist zu restriktiv - Sie müssen den vollständigen Pfad angeben. Ich habe meine Version geändert und^durch/ersetzt. – Trejkaz

8

load 'filename.rb'

einer nach dem anderen für jeden, der geändert wurde ...

6

Eine Möglichkeit ist Kernel#load zu verwenden. Sie können es ähnlich wie Kernel#require verwenden, außer dass Sie die Dateierweiterung explizit einschließen müssen. Es hat jedoch seine Nachteile (selbst etwas so einfaches wie class Foo < Struct.new(:foo); end scheitert, da es nicht möglich ist, die Superklasse einer Klasse zu ändern), also würde ich auch gerne einen besseren Weg kennen, dies zu tun.

In Schienen können Sie dies mit reload! auf Skript/Konsole erreichen, aber ich weiß nicht, welche Art von Magie sie verwenden.

This gist sieht vielversprechend aus, aber ich habe es nicht getestet.

+0

'reload!' Soll nur Dinge im 'app /' Verzeichnis laden, sonst nichts. Auch hier gibt es Einschränkungen. Aus diesem Grund erscheinen viele Ihrer Klassen und Controller als anonyme Klassen in Ihrer Entwicklungsumgebung, sodass sie bei jeder Anfrage vollständig gelöscht und neu initialisiert werden können. – tadman