2010-09-21 2 views
6

Dire che ho apportato una modifica a una libreria Clojure (ad esempio, ho aggiunto un parametro al token di richiesta in clj-oauth) e voglio usare quella libreria modificata nel mio progetto. Qual è il modo migliore per farlo, a meno di compilare la nuova libreria come JAR e copiarla nel mio progetto lib?Come utilizzare le mie versioni delle librerie Clojure?

Voglio essere in grado di modificare la libreria e il mio progetto allo stesso tempo (preferibilmente nel REPL). Se lo facessi in Ruby, scaricherò e "richiederò" la gemma, quindi riaprirò quella classe nella mia origine del progetto e aggiungerò o sovrascriverò i metodi secondo necessità.

risposta

6

È possibile eseguire l'hacking direttamente su REPL. Supponiamo che tu abbia incanter sul tuo classpath. Avvia un REPL. La prima cosa che dobbiamo fare è coinvolgere le classi di incanter.

user> (require 'incanter.core) 
nil 

Ora possiamo vedere la funzione incanter.core/matrice?

user> (incanter.core/matrix? 2) 
false 

Possiamo guardare il codice sorgente originale:

user> (require 'clojure.repl) 
nil 
user> (clojure.repl/source incanter.core/matrix?) 
(defn matrix? 
    " Test if obj is 'derived' incanter.Matrix." 
    ([obj] (is-matrix obj))) 
nil 

Andiamo a rovinare tutto:

Primo cambio al namespace incanter.core:

user> (in-ns 'incanter.core) 
#<Namespace incanter.core> 

Quindi possiamo ridefinirlo usando il vecchio codice sorgente come culla:

incanter.core> (defn matrix? [obj] "hello") 
#'incanter.core/matrix? 

prova Unità:

incanter.core> (matrix? 2) 
"hello" 

tornare al namespace utente:

incanter.core> (in-ns 'user) 
#<Namespace user> 

Prova ora:

user> (matrix? 2) 
; Evaluation aborted. 

Non esiste una definizione di utente/matrice. Lo abbiamo ridefinito nel namespace incanter.core.

user> (incanter.core/matrix? 2) 
"hello" 

per la sperimentazione presso il repl, è ok solo per cambiare i file sorgente e ricompilare il singolo file (CC Ck in emacs), o se siete nello spazio dei nomi a destra, appena ri-valutare la definizione .

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Ora, se vogliamo rendere permanente il nostro prezioso cambiamento e renderlo disponibile ad altri progetti, dipende da come viene impostato tutto.

Io uso Maven per la gestione delle dipendenze, quindi sarebbe una questione di modifica del file di origine, quindi rieseguirò il processo di compilazione per la libreria per compilare la nuova versione e installarla nel repository di Maven locale.

Con un progetto Maven, che dovrebbe essere semplice come

$ mvn install 

Una nota sui numeri di versione:

Se si fanno modifiche permanenti e utilizzare la gestione delle dipendenze per coordinare le differenze, allora si dovrebbe cambia il numero di versione della tua libreria, da forse 1.2.0 a 1.2.0-johnshack-SNAPSHOT, o qualcosa che è improbabile che vada in collisione con la cosa reale quando vuoi usare una versione non protetta in un altro progetto. Non vorrai che una versione modificata trovi la sua strada in progetti in cui non è il benvenuto.

Quindi si modificano i propri file di progetto per assicurarsi di utilizzare la versione compromessa dove si desidera, e la prossima volta che si avvia il repl, si dovrebbe inserire l'ultimo hack che è stato installato.

Sarà necessario reinstallarlo nuovamente ogni volta che si desidera che le modifiche si introducano nel repository, ma in realtà è probabilmente una buona cosa.

Sfortunatamente, (ed è stato a questo punto che ho iniziato a desiderare di aver scelto un esempio diverso) Incanter si rivela essere un progetto leiningen che è suddiviso in sottomoduli in un tipo di script ad hoc , quindi abbiamo bisogno di capire come dovrebbe essere installato. Il risultato è stato piuttosto difficile, anche se la risposta è semplice. Leiningen mi dà fuoco.

è possibile ottenere fonte di incanter qui:

$ git clone http://github.com/liebke/incanter.git

e il file sorgente rilevante è:

~/incanter/modules/incanter-core/src/incanter/core. clj

Modifica per interrompere la matrice? funzione, e quindi si scopre che quello che devi fare è:

Modificare i numeri di versione sia nel livello superiore project.clj, sia nel sottomodulo project.clj.

Quindi eseguire lein install nella directory incanter-core e quindi di nuovo nella directory di livello superiore e devi farlo in questo ordine. Non capisco perché.

Al momento tutto sembra inutilmente complicato. Sono (abbastanza) sicuro che si sistemerà mentre gli strumenti maturano.

4

Se si sta utilizzando (o non si preoccuperebbe di utilizzare) cake, consultare la sezione delle dipendenze del sottoprogetto del README. Penso che potrebbe essere esattamente quello che stai cercando.

-1

L'upload in clojars con un nome diverso dipende da quello.

+1

Oppure utilizzare un repository Maven locale – Greg

+0

Con Leiningen, questo può essere fatto utilizzando 'lein install'. – Mars