क्या मैं एक पुस्तकालय को फिर से लोड कर सकता हूं और मानों को फिर से असाइन कर सकता है?


10

मैं एक पुस्तकालय विकसित कर रहा हूं और इसे Emacs से बाहर निकाले बिना संपादन के बाद फिर से लोड करना चाहूंगा (मान लें कि यह चालू है load-path):

(load-library "myname")

जब मैं ऐसा करता हूं, तो Emacs defvarइनबाउंड वैरिएबल में बदलाव नहीं करता है ।

मैं प्रत्येक शीर्ष स्तर के फॉर्म पर मैन्युअल रूप से कॉल eval-defun( C-M-x) नहीं करना चाहता । M-x eval-bufferसम्मान करता है defvar/ defcustom?


1
शायद (unload-feature 'myname)पहले?
npostavs

बस यह कोशिश की और नहीं, इसके विपरीत eval-defunमें परिवर्तन नहीं उठाता है defvar
जीनपिएरे

1
@ कौशलमोडी: मुझे नहीं लगता कि यह कोई डुप्लिकेट है। यह प्रश्न defvarएक फ़ाइल या बफर में सभी एस पर अभिनय करने के बारे में है, अगर मैं सही ढंग से समझता हूं।
आकर्षित किया

1
आम तौर पर किसी को सिर्फ दोष निकालने की जरूरत नहीं होगी । इसके अलावा, ओपी का load-fileमतलब है कि वह पूरी फाइल का मूल्यांकन करना चाहता है, जबकि यह सुनिश्चित करता है कि चूक का पुनर्मूल्यांकन किया गया है।
कौशल मोदी

2
मूल्यों को बदलते हुए मेरा अपना दृष्टिकोण ईश्वर-अवगुण है। यह मेरे लिए प्रयोग करने योग्य होने के लिए पर्याप्त नहीं है। YMMV।
यंगफ्रॉग

जवाबों:


3

(progn (unload-feature 'your-lib) (load-library "your-lib"))

यह तब तक काम करेगा जब तक आप पहले पुस्तकालय को emacs के माध्यम से लोड करके डिफॉवर्स लोड करते हैं, और उपयोग नहीं करते हैं eval-defun, eval-bufferआदि।

जब आप उपयोग करते हैं require, load-libraryआदि Emacs का ध्यान रखेंगे कि कौन से चर और फ़ंक्शन आपकी लाइब्रेरी का हिस्सा हैं, और आपके द्वारा उपयोग किए जाने पर उन्हें पूरी तरह से हटा देंगे unload-feature

पैकेज लिखते समय, मुझे लगता है कि ऊपर दिए गए कोड का उपयोग करने से बेहतर समाधान है eval-defunक्योंकि आप नए कोड लिखते हैं ताकि आप मध्यवर्ती राज्यों में न जाएं।


(info "(elisp) Loading"), (info "(elisp) Unloading")और यदि पुस्तकालय किसी अन्य पुस्तकालय के लिए निर्भरता है तो arg की unload-featureआवश्यकता होती forceहै। बहुत बढ़िया जवाब! मैं सोच रहा हूँ कि Emacs संस्करण अनलोडिंग प्रदान करने के लिए क्या शुरू करता है ...
gavenkoa

3

defvarवैरिएबल के मान को उसी तरह से पुन: असाइन नहीं करता है, जैसे कि, setqया setf। एक बार एक वैरिएबल का मान होने के बाद, defvar उसे स्पर्श नहीं किया जाएगा।

से defvarकी docstring:

(defvar SYMBOL &optional INITVALUE DOCSTRING)

SYMBOL को एक चर के रूप में परिभाषित करें, और SYMBOL लौटें।

...

वैकल्पिक तर्क INITVALUE का मूल्यांकन किया जाता है, और SYMBOL सेट करने के लिए उपयोग किया जाता है, केवल अगर SYMBOL का मूल्य शून्य है। यदि SYMBOL बफर-लोकल है, तो इसका डिफ़ॉल्ट मान सेट है; बफर-स्थानीय मान प्रभावित नहीं होते हैं। यदि INITVALUE गायब है, तो SYMBOL का मान सेट नहीं है।

...

चूँकि defvarजब आप पहली बार लायब्रेरी को लोड करते हैं, तो उन्हें मान देने के लिए विचारणीय रूप से वैरिएबल को एड करें, लायब्रेरी को पुनः लोड करने से मान नहीं बदलेंगे।

डिफाइनिंग ग्लोबल वैरिएबल पर एलीश मैनुअल नोड भी देखें ।

पर भरोसा करने के बजाय defvar, आप हमेशा मूल्यों को फिर से असाइन कर सकते हैं setq। एक विकल्प के रूप में, क्लंकी विकल्प, आप uninternप्रतीक कर सकते हैं ताकि defvarएस उन्हें फिर से लोड करने पर न मिले:

(defvar test-1 "test this")
(defvar test-2 "test this one, too")

test-1                                  ; => "test this"
test-2                                  ; => "test this one, too"

(defvar test-1 "trying to redefine")
(defvar test-2 "trying to redefine, too")

test-1                                  ; => "test this"
test-2                                  ; => "test this one, too"

(mapc #'unintern '(test-1 test-2))

test-1                                  ; => error!
test-2                                  ; => error!

(defvar test-1 "trying to redefine")
(defvar test-2 "trying to redefine, too")

test-1                                  ; => "trying to redefine"
test-2                                  ; => "trying to redefine, too"

2
इस संदर्भ में, यानी, जब एक विशिष्ट पैकेज विकसित किया जाता है, तो defvarउपयोग करने के लिए सही चीज है। setqअलग-अलग उपयोगकर्ताओं द्वारा स्थापित क्लॉबर अनुकूलन होगा। ओपी पैकेज डेवलपमेंट के दौरानdefvar वेरिएबल्स की ओवर राइटिंग के लिए रास्ता बनाने के लिए कह रहा है । पैकेज जारी होने पर वापस स्विच करने की आवश्यकता होगी । setqdefvar
टायलर

@ टायलर, हां, मैं मानता हूं कि defvarपैकेज विकास के लिए उपयुक्त है। मैं केवल इंगित कर रहा हूं कि defvarमूल्यों को फिर से असाइन नहीं किया जाता है , जबकि setqकरता है।
दान

2

इसे इस्तेमाल करे:

(defun foo ()
  "(Re-)evaluate all `defvar's in the buffer (or its restriction)."
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (not (eobp))
      (when (re-search-forward "\\s-*(defvar \\([^ \t\n(\"]+\\)[ \t\n]+[^)]" nil 'MOVE)
        (let ((old-value (make-symbol "t"))
              new-value value)
          (let ((debug-on-error old-value))
            (setq value (eval-defun-2))
            (setq new-value debug-on-error))
          (unless (eq old-value new-value)
            (setq debug-on-error new-value))
          value)))))

वह केवल उसी कोड का eval-defunउपयोग करता है जो a पर उपयोग करता है defvar। यह बफर (या इसके प्रतिबंध को संकीर्ण करके) का पता लगाता है, प्रत्येक पर रोक रहा है defvarऔर उस eval-defunपर कोड का उपयोग कर रहा है।


1

जब मैंने सुना कि बफर के पुनर्मूल्यांकन के लिए कोई सुविधाजनक उपाय नहीं है, तो मैं इस बात का पुन: निर्धारण करता defvarहूं कि मैं क्या करूं eval-defun:

(defun my/eval-buffer ()
  "Evaluate entire buffer with re-assigning values to `defvar' / `defcustom'.
Useful during package development."
  (interactive)
  (save-excursion
    (beginning-of-buffer)
    (while (not (eobp))
      (eval-defun nil)
      (end-of-defun))))

eval-defun-2कार्यान्वयन से प्रेरित कोड संरचना । यह एक बचाव के मूल्यांकन का बल कैसे दिया जाए? समाधान।

मूल रूप से मैं लाइब्रेरी का फिर से मूल्यांकन करने के लिए उच्च स्तरीय फ़ंक्शन चाहता हूं जो बिल्ड स्क्रिप्ट के माध्यम से फिर से स्थापित हो:

(defun my/load-library (library)
  "Evaluate entire library with re-assigning values to `defvar' / `defcustom'.
Useful during package development."
  (interactive
   (list (completing-read "Load library: "
                          (apply-partially 'locate-file-completion-table
                                           load-path
                                           '("" ".el")))))
  (with-temp-buffer
    (insert-file-contents (locate-file library load-path '("" ".el")))
    (my/eval-buffer)))

आकर्षित समाधान नेस्टेड पर भी काम करता है defvarलेकिन कोड को पूरी तरह से समझना मुश्किल है।

मैं uninternप्रतीक उपसर्ग / regex पर आधारित सभी प्रतीकों के बारे में भी सोचता हूं (जैसा कि डैन ने सुझाव दिया है) लेकिन मैं हर बार उपसर्ग टाइप करने के लिए आलसी हूं ... देखें कि मैं एक निश्चित उपसर्ग के साथ सभी प्रतीक परिभाषाओं को कैसे खोल सकता हूं?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.