2015-08-29 9 views
6

uberjar oluştururken "Lieningen" davranışını anlamaya çalışıyorum.Neden "lein uberjar", "def" ile tanımlanan değişkenleri değerlendiriyor?

(ns my-stuff.core 
    (:gen-class)) 

(def some-var (throw (Exception. "boom!"))) 

(defn -main [& args] 
    (println some-var)) 

bu lein run ile yürütüldüğünde bu açıkça bir özel durum ile başarısız: Aşağıdaki davranış reproduces az bir örnektir. Ancak, neden lein uberjar yürütme neden değişken tanımından bir özel durum ile başarısız olduğunu anlamıyorum? Neden lein uberjar çalıştırıldığında değişken değeri değerlendirilmeye çalışılır? Bu, uberjar görevine özgü mi yoksa Clojure veya Leiningen hakkında daha önemli bir şey mi eksik?

cevap

10

Uberjar için ad alanınızı derlemek için (AOT'niz açıksa), clojure derleyicisi ad alanınızı yüklemelidir. Bu her zaman en üst düzey yan etkilere yol açacaktır.

Bunun üstesinden gelmenin en iyi yolu, üst düzey kodda (def formunun içinde veya dışında olsun) hiçbir zaman yan etkilere sahip olmamak ve başlangıç ​​gerektiren tüm yan etkileri gerçekleştirmek için başlatma işlevlerine sahip olmaktır.

bir geçici çözüm derlenirken zamanında ama senin kodun geri kalanını yüklemek için iç gözlem kullanan küçük ad yapmak olabilir - Böyle bir fonksiyonu kullanarak: o ad derlenmiş olup olmadığını

(defn -main 
    [] 
    (require 'my.primary.ns) 
    ((resolve 'my.primary.ns/start))) 

, jvm -main'i bulabilir ve çalıştırabilir, diğer kodlarınızdan hiçbiri derlenmez. Çalışma zamanı require, Clojure derleyicisinin kodunuzun geri kalanını yalnızca çalışma zamanında yüklemesine neden olacak ve -main temiz olarak derlenecek şekilde resolve'a ihtiyaç duyuyor - başvurulan var olanı döndürüyor, sonra çağrıldığında işlevinizi çağırıyor.

İlgili konular