2016-08-07 13 views
8

यह मेरे साथ बार-बार होता है: मैं कक्षा को परिभाषित करता हूं और भूल जाता हूं कि मैं इसे मजेदार बनाना चाहता हूं या कहता हूं, जीटीके विजेट क्लास, इस प्रकार मेटाक्लास को बताया जाना चाहिए। एक बार यह परिभाषित हो जाने के बाद, एसबीसीएल मुझे मुझे मेटाक्लास को बदलने नहीं देता है (भले ही इस वर्ग का कोई उदाहरण न हो)। उदाहरण के लिए,कक्षा के मेटाक्लास को कैसे बदलें

(defclass foo() 
    ((slot-a))) 

का मूल्यांकन और फिर एक metaclass जोड़ने और फिर से मूल्यांकन करने: त्रुटि में

(defclass foo() 
    ((slot-a)) 
    (:metaclass gobject:gobject-class)) 

परिणाम:

Cannot CHANGE-CLASS objects into CLASS metaobjects. 
    [Condition of type SB-PCL::METAOBJECT-INITIALIZATION-VIOLATION] 
See also: 
    The Art of the Metaobject Protocol, CLASS [:initialization] 

दुर्भाग्य से मैं कला की एक प्रति की जरूरत नहीं है मेटाबोजेक्ट प्रोटोकॉल का यह जांचने के लिए कि यह क्या कहता है। अभी के लिए एकमात्र तरीका मैं समझ सकता हूं कि लिस्प को पुनरारंभ करना है, जो काफी विघटनकारी हो सकता है।

चूंकि मुझे जल्द ही त्रुटि का एहसास हुआ है, इसलिए मुझे परिभाषित कक्षा को पूरी तरह से हटाकर ध्यान में रखना नहीं है। प्रश्न:

  • यदि मैंने कक्षा के उदाहरण बनाए हैं, तो क्या उन्हें खोजने और उन्हें जीसीड प्राप्त करने का कोई तरीका है?
  • कक्षा को कैसे हटाएं? कार्यों के लिए fmakunbound की तरह कुछ।

उत्तर

9

Unfortunately I don't have a copy of The Art of the Metaobject Protocol to check what it says.

हालांकि मैं किताब पढ़ने की सलाह देते हैं, तो आप कुछ जानकारी ऑनलाइन प्राप्त कर सकते हैं। उदाहरण के लिए देखें ENSURE-CLASS-USING-CLASS

How to remove the class?

आप (SETF FIND-CLASS) उपयोग कर सकते हैं:

(setf (find-class 'foo) nil) 

या, आप कल्पना कीचड़ निरीक्षक का उपयोग कर सकते हैं। कक्षा के नाम को इंगित करते समय आप slime-inspect-defintion पर कॉल करते हैं। फिर, आप नाम देखेंगे। जब आप इसे चुनते हैं, तो आप अपनी कक्षा का नामकरण करने वाले प्रतीक का निरीक्षण करते हैं। उसके बाद, आप की तरह कुछ देख सकते हैं:

It names the class FOO [remove] 

परंतु FOO केवल एक वर्ग के नाम, आप बड़ा हथौड़ा का उपयोग कर सकते हैं:

(unintern 'foo) 

If I have created instances of the class, is there a way to find them to nullify them and get them GCed?

नहीं, केवल जी सी वैश्विक दृष्टिकोण है, और व्यावहारिक कारणों से, यह आमतौर पर पिछड़े संदर्भों को नहीं रखता है कि किसी विशेष वस्तु (और कैसे) का संदर्भ कौन देता है। कक्षा के सभी उदाहरणों का कोई वैश्विक रिकॉर्ड नहीं है जब तक कि आप उन्हें स्टोर करने के लिए अपनी खुद की (कमजोर) हैश-टेबल पेश नहीं करते। लेकिन अगर आपने अपने सभी उदाहरणों का रिकॉर्ड रखा है, तो आप उन्हें CHANGE-CLASS कर सकते हैं। उदाहरण के लिए, आप को परिभाषित:

(defclass garbage()()) 

... आपके वस्तु में किसी भी पहले से आयोजित संदर्भ में जारी किया जाएगा और जीसी जहां संदर्भित वस्तुओं के अपने उदाहरणों निपटान के लिए एक अवसर है। और जब कोई अन्य वस्तु 'कचरा' का एक उदाहरण संदर्भित करती है, तो आप इसे अपडेट कर सकते हैं। 'कचरा का उपयोग करने के बजाय, आप शायद पुराने वर्गों के उदाहरणों को अपनी नई कक्षा में बदल सकते हैं (नाम वही है, लेकिन वर्ग वस्तु अलग है)। ध्यान दें कि CHANGE-CLASS एक सामान्य कार्य है।


। कार्यान्वयन ढेर वॉकर प्रदान कर सकते हैं। उदाहरण के लिए देखें Heap walkers in Allegro CL

संबंधित मुद्दे