2010-08-11 17 views
19

Esiste un modo per "ricaricare" o "aggiornare" un rubygem in memoria? Dato che sto giocando in irb, a volte mi piace modificare i miei file gem e, se richiedo la stessa gemma, non si aggiorna in memoria e dà l'output "false". Attualmente devo uscire da IRB, tornare in IRB e quindi richiederlo nuovamente, ci deve essere un modo migliore ... che cos'è?Ricarica rubygem in IRB

+0

se dovessi codificare questa funzionalità in dove dovrebbe andare? RubyGems? Questa comunità accetta generalmente nuove richieste di pull di funzionalità? – Schneems

risposta

17

Come altri hanno suggerito, è possibile utilizzare il # Kernel load. . Tuttavia, non perdete il vostro tempo a cercare e caricare ogni file gemma come tutti i file che sono stati richiesti sono memorizzati in $" Armati di questa conoscenza, ecco un comando IRB reload:

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

Ad esempio, se si sono stati utilizzando la gemma hirb in IRB, si sarebbe semplicemente ricaricare con:

>> reload 'hirb' 

Se per qualsiasi motivo il carico non funziona (è più esigente circa le estensioni dei file che richiede è), è possibile ri-richiedono alcun file per prima cosa cancella la sua voce in $ ". Con questo consiglio il comando di cui sopra sarebbe:

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

Scegliere quello che funziona per voi. Personalmente, io uso quest'ultimo.

+0

Funziona anche per gli script inclusi dal filesystem? Non ha funzionato per il mio ... e la mia istruzione require si presenta così: 'richiede "# {File.expand_path (__ FILE __)} /../ lib/query"' – picardo

+2

Non lo fa, no. La regex è troppo restrittiva: devi specificare il percorso completo. Ho modificato la mia versione, sostituendo^con /. – Trejkaz

8

carico 'filename.rb'

uno alla volta per ogni che è stato cambiato ...

6

Un modo è quello di utilizzare Kernel#load. Puoi usarlo praticamente come Kernel#require, tranne per il fatto che devi includere esplicitamente l'estensione del file. Tuttavia, ha i suoi svantaggi (anche qualcosa di semplice come class Foo < Struct.new(:foo); end fallisce, dato che non è possibile cambiare la superclasse di una classe), quindi mi piacerebbe anche conoscere un modo migliore per farlo.

In rotaie è possibile ottenere questo con su script/console, ma non so che tipo di magia che usano.

This gist sembra promettente ma non l'ho provato.

+0

'reload!' Si suppone solo di caricare cose nella directory 'app /', niente di più. Ci sono anche limitazioni a questo, motivo per cui molte classi e controllori vengono visualizzati come classi anonime nel proprio ambiente di sviluppo in modo che possano essere eliminati completamente e reinizializzati su ogni richiesta. – tadman