2012-03-20 20 views
9

के अंदर नहीं, सामान्य लिस्प कोड लिखते समय, मैं SLIME का उपयोग करता हूं। विशेष रूप से, मैं सी-सी सी-के उपयोग करके कार्यों की परिभाषाओं वाले बफर को संकलित करता हूं, और फिर उन कार्यों को चलाने के लिए REPL पर स्विच करता हूं। बफर में उन कार्यों को चलाने के लिए निष्पादन योग्य कोड डालना इतना अच्छा काम नहीं करता है। अगर कोड में बग है तो यह गड़बड़ कर सकता है।सामान्य लिस्प कोड जो कमांड लाइन से निष्पादित करता है, लेकिन दुभाषिया

यह कोड शामिल करने का एक तरीका है जो बफर में संकलित नहीं होता है, लेकिन कमांड लाइन से चलाएं, उदाहरण के लिए जब

sbcl --script foo.lisp 

कर अगर ऐसी बात है तो मैं हर बार जब मैं कमांड लाइन से कोड को चलाने के लिए चाहते थे जोड़ने और कोड को निकालने के रखने की जरूरत नहीं होगी। क्या ऐसी स्थिति मौजूद है?

यह पायथन स्थिति के समान है।

if __name__=='__main__': 

जो गलत है अगर एक अजगर फ़ाइल एक मॉड्यूल के रूप में आयात, लेकिन सच है अगर यह एक स्क्रिप्ट के रूप में चलाया जाता है।

इस ब्लॉग पोस्ट "Using SBCL for Common Lisp shell scripting" हकदार, यादृच्छिक Googling द्वारा पाया,

;; If run from command line, the following if-test will succeed 

(if (> (length sb-ext:*posix-argv*) 1) 

    ;; Code that is executed from the command line only goes here 

) 

कोड वास्तव में शामिल कीचड़ के अंदर संकलक द्वारा चलाए जा नहीं प्राप्त करता है, लेकिन यह sbcl --script द्वारा या तो नहीं चला हो जाता है।

अद्यतन: उनके सहायक उत्तर और अनुवर्ती अनुवर्ती के लिए Vsevolod Dyomkin के लिए धन्यवाद। उस उत्तर के बारे में कुछ नोट्स टिप्पणियों से उस उत्तर में संकलित किए गए हैं। @Vsevolod, यदि आप इन्हें अपने उत्तर में जोड़ते हैं, तो मैं उन्हें हटा दूंगा।

  1. सबसे पहले, मैंने कमांड लाइन से कोड चलाने का तरीका पूछा, लेकिन दुभाषिया से नहीं। आपूर्ति समाधान अधिक करता है; यह दुभाषिया से कोड चलाने का एक तरीका भी देता है लेकिन कमांड लाइन नहीं।

  2. पहला चरण मैक्रो वर्ण #! के लिए reader macro function को परिभाषित करना है। लिंक में कहा गया है "एक मैक्रो चरित्र का सामना करने पर, लिस्प पाठक अपने पाठक मैक्रो फ़ंक्शन को कॉल करता है"। पाठक फ़ंक्शन को कॉल द्वारा set-dispatch-macro-character पर परिभाषित किया गया है। तो, जब #! चरित्र देखा जाता है, set-dispatch-macro-character शरीर में लैम्ब्डा फ़ंक्शन को परिभाषित करने का कारण बनता है। यह फ़ंक्शन :noscript को *features* चर में कीवर्ड जोड़ता है। एसओ प्रश्न Read macros: what do you use them for? में पाठक मैक्रोज़ के लिए क्या अच्छा है, इसकी एक चर्चा भी देखें।

  3. ध्यान दें कि :noscript*features* में जोड़ा गया है जब #! वर्ण मौजूद है। इसके अलावा, #! वर्ण मौजूद है जब कोड दुभाषिया के अंदर चलाया जाता है उदा। slime का उपयोग करते समय, लेकिन स्पष्ट रूप से
    sbcl --script द्वारा पाठ अनुपस्थित (हटाया गया) अनुपस्थित है। इसलिए, :noscript को *features* में जोड़ा गया है जब कोड इंटरपेटर में चलाया जाता है, लेकिन
    स्क्रिप्ट के रूप में चलाने पर नहीं।

  4. अब हम बिल्टिन रीडर मैक्रोज़ #-/#+ का उपयोग करते हैं, जो Vsevolod ने कहा, सी के #IFDEF/#IFNDEF के समान व्यवहार करते हैं। वे
    *features* में एक प्रतीक की जांच करते हैं। इस मामले में, :noscript की अनुपस्थिति के लिए चेक करता है, और #+:noscript:noscript की उपस्थिति के लिए चेक करता है।
    यदि वे शर्तें संतुष्ट हैं, तो यह संबंधित कोड चलाता है। कोड के ब्लॉक को लपेटने के लिए, कोई progn का उपयोग इस प्रकार कर सकता है: #-:noscript (progn <your code here>)

  5. अंत में, इस कार्यक्षमता का उपयोग करने वाले कोड चलाने से पहले set-dispatch-macro-character पर कॉल करने की आवश्यकता है। sbcl के मामले में, कोई प्रारंभिक फ़ाइल ~/.sbclrc में डाल सकता है। निरीक्षण करें कि यह दृष्टिकोण एसबीसीएल के सामान्य लिस्प कार्यान्वयन पर निर्भर नहीं है।

  6. एक आसान विकल्प, SBCL-devel सूची में उल्लिखित के रूप में, तथ्य यह है कि कीवर्ड :SWANK प्रकट होता है जब एक प्रकार
    एक आरईपीएल में *features* Emacs अंदर कीचड़ का उपयोग कर उपयोग करने के लिए है। स्वैंक एसएलईएमई का सर्वर पक्ष है। एसएलआईएमई को एसएलईएमई/स्वैंक नामक अधिक सटीक रूप से जाना चाहिए, क्योंकि ये दो क्लाइंट-सर्वर आर्किटेक्चर के क्लाइंट/सर्वर घटक हैं। मुझे इस ब्लॉग पोस्ट को Understanding SLIME कहा गया, जो सहायक था।

    तो, एक बस #-:noscript और #+:noscript तरह #-:swank और #+:swank उपयोग कर सकते हैं, सिवाय इसके कि एक किसी भी कोड लिखने की जरूरत नहीं है। बेशक, यह तब काम नहीं करेगा यदि कोई कमांड लाइन दुभाषिया sbcl का उपयोग कर रहा है, उदाहरण के लिए, तब से :SWANK*features* में दिखाई नहीं देगा।

उत्तर

12

आप निम्न चाल का उपयोग कर सकते हैं:

(set-dispatch-macro-character #\# #\! 
    (lambda (stream c n) 
     (declare (ignore c n)) 
     (read-line stream) 
     `(eval-when (:compile-toplevel :load-toplevel :execute) 
     (pushnew :noscript *features*)))) 
  • अपनी स्क्रिप्ट फ़ाइल उपयोग #-:noscript में:

    #!/usr/local/bin/sbcl --script 
    
    (defun test (a) (print a)) 
    
    (test 1) 
    #-:noscript (test 2) 
    #+:noscript (test 3) 
    

    1. कुटिया के लिए एक प्रेषण समारोह को परिभाषित करें 01 निष्पादित1 और 2 प्रिंट होगा, जबकि प्रतिलिपि सी.के. इच्छा उत्पादन 1 और 3.

    संपादन

    यह चाल काम करना चाहिए, क्योंकि कुटिया लाइन sbcl --script से पूरी तरह हटा दिया जाता है, लेकिन उसे निकाला नहीं , जब फ़ाइल एसएलईएमई या अन्य तंत्र के माध्यम से लोड की जाती है।

    इस दृष्टिकोण की कमी यह है कि हम सुविधाओं में :noscript की अनुपस्थिति पर स्थिति रखते हैं, और :script की उपस्थिति नहीं है। इसे संशोधित करने के लिए, उपयुक्त सुविधा को धक्का देना sbcl --script प्रसंस्करण में ही किया जाना चाहिए।

  • +0

    दिलचस्प लग रहा है। प्रश्न: 'सेट-प्रेषण-मैक्रो-कैरेक्टर' आमंत्रण कहां होगा? और/या, क्या आप आम तौर पर समझा सकते हैं * कैसे * (और/या * क्यों *) यह काम करेगा? मैं एक सीएल नौसिखिया हूं, और यहां कुछ चीजों में से एक यह है कि आप वर्णों को '#' और '! 'का संदर्भ दे रहे हैं, लेकिन फिर' # + 'और' # -' के लिए तर्क है ... I मुझे यकीन है कि मुझे कुछ याद आ रहा है, मैं बस इतना नहीं जानता कि मैं क्या खो रहा हूं। :) (हालांकि शायद मूल पूछताछ में यह समस्या नहीं है, मुझे नहीं पता।) – lindes

    +2

    शेबांग लाइन को 'sbcl --script' द्वारा प्रोग्राम के पाठ से हटा दिया गया है, और जब आप फ़ाइल को किसी अन्य तरीके से लोड करते हैं तो हटा नहीं दिया जाता है। '# -' /' # + 'मानक पढ़ने वाले मैक्रोज़ सी के' # IFDEF'/'IFNDEF' के समान हैं। वे '* विशेषताएं *' में एक प्रतीक की जांच करते हैं। हम '#!' के लिए एक पढ़ा हुआ मैक्रो परिभाषित करने के लिए 'noscript' को' * विशेषताएं * 'दबाएं। फाइल लोड होने से पहले इसे परिभाषित किया जाना चाहिए। दुर्भाग्यवश आप इसे अधिक उचित नहीं कर सकते हैं और स्क्रिप्ट आमंत्रण में 'स्क्रिप्ट' दबा सकते हैं, क्योंकि उस समय यह पंक्ति अनुपस्थित है। आप यहां पढ़ने मैक्रोज़ के उपयोगों के बारे में अधिक पढ़ सकते हैं: http://stackoverflow.com/questions/1351956/read-macros-what-do-you-use-them- –

    +0

    हाय Vsevolod के लिए। धन्यवाद, यह काम करता है। क्या आप अधिक विस्तार से और अधिक सरल रूप से रेखांकित कर सकते हैं। यहाँ क्या हो रहा है? मैं इस समय लिस्प के बारे में कुछ भी नहीं जानता। आरंभ करने के लिए, आप अपने कोड में पढ़ने वाले मैक्रो को कहां परिभाषित करते हैं? प्रश्न में मैक्रोज़ '# -/# +' हैं? मुझे एक 'defmacro' नहीं दिख रहा है। एक और व्यावहारिक नोट पर, क्या मुझे हर पंक्ति को उपसर्ग करने की ज़रूरत है जिसे मैं विशेष रूप से '#:: noscript' या इसी तरह से संभाला जाना चाहता हूं? मैं एक 'if' कथन की तरह कुछ की उम्मीद कर रहा था जिसे मैं एक बार कोड के पूरे ब्लॉक के चारों ओर लपेट सकता था। –

    4

    फारे राइडौ ने निफ्टी यूनिक्स उपयोगिता सीएल-लॉन्च लिखा, जो कमांड लाइन से लिस्प सॉफ़्टवेयर निष्पादित करने में सक्षम बनाता है। इसने क्विकलिस्प समर्थन को एकीकृत किया है और अधिकांश सामान्य लिस्प कार्यान्वयन पर काम करता है।

    उदाहरण स्क्रिप्ट ऐसी दिखाई देगी हो सकता है:

    #!/usr/bin/cl -sp "hunchentoot" -Q -E main 
    
    (defun main (argv) 
        (format t "~A: ~{~A ~}~%" (truename ".") argv) 
        (hunchentoot:start 
        (make-instance 'hunchentoot:acceptor 
            :document-root (truename ".") 
            :port 8080)) 
        (do ((x #\s (read-char))) 
         ((char-equal x #\q) nil))) 
    

    स्क्रिप्ट के + x अनुमतियों को जोड़ने और यह लागू करने के बाद, यह मौजूदा निर्देशिका में http सर्वर शुरू कर देंगे। "-sp" ध्वज उस पैकेज को इंगित करता है जिसे आप लोड करना चाहते हैं, इसलिए पैकेज से खोल स्क्रिप्ट को सारणीबद्ध करने का यह काफी साफ तरीका है।

    अधिक जानकारी के लिए देखें: http://cliki.net/CL-Launch

    +0

    उत्तर के लिए धन्यवाद, डैनियल। –

    +0

    नया [रोसवेल] (https://github.com/roswell/roswell) भी है, जो क्ल-लॉन्च जैसे स्क्रिप्ट लॉन्चर होने के अलावा, एक कार्यान्वयन इंस्टॉलर, एक स्क्रिप्ट मैनेजर/डाउनलोडर, बिल्डिंग यूटिलिटी इत्यादि भी है। [ कुछ lispers] (http://eudoxia.me/article/common-lisp-sotu-2015) रोसवेल पर निर्माण करने की सलाह देते हैं, और अब क्ल-लॉन्च नहीं करते हैं। – Ehvince

    0

    मैं एक ही सवाल था और मैं सिर्फ इस चर्चा पर ठोकर खाई है। कम से कम एसबीसीएल के साथ ऐसा लगता है कि मैं (sb-ext:posix-getenv "_") का उपयोग कर सकता हूं। जब कीचड़ में चलाया जाता है तो यह /usr/bin/emacs (या जो भी emacs का मार्ग है) देता है और अन्यथा मैं जिस स्क्रिप्ट का उपयोग स्क्रिप्ट को आमंत्रित करने के लिए करता हूं। तो जब तक आप एक emacs योगदानकर्ता नहीं होते हैं तब तक कीचड़ और स्क्रिप्ट आमंत्रण के बीच अंतर करना हमेशा संभव होता है :)

    यदि आप स्क्रिप्ट का पूरा पथनाम प्राप्त करना चाहते हैं, तो आप (truename (sb-ext:posix-getenv "_")) का उपयोग कर सकते हैं। हालांकि, जब कीचड़ से चलते हैं तो यह प्रभावी emacs पथनाम वापस कर देगा, उदा। /usr/bin/emacs-24.5, इसलिए यह कम सुविधाजनक हो सकता है।