2012-11-01 11 views
13

मैं क्लोजर instance? फ़ंक्शन द्वारा थोड़ा उलझन में हूं। यह एक भी तर्क लेने में काफी खुश लगता है। तोक्लोजर इंस्टेंस? एकल तर्क

(instance? String) 

ठीक काम करता है, लेकिन हमेशा झूठा होता है।

क्या मुझे यहां कुछ याद आ रही है? मैंने इसे दो दिनों में दो बार किया है, और दोनों बार मुझे डीबग करने में काफी लंबा समय लगता है (हाँ, मैं मानता हूं कि गलती करने के लिए एक बार दुर्भाग्य के रूप में माना जा सकता है, लेकिन दो बार लापरवाही की तरह दिखता है)।

एक धैर्य त्रुटि के साथ क्यों नहीं टूटता है?

नोट बाद में जोड़ा गया: क्लोजर 1.6 के रूप में यह तय किया गया है!

http://dev.clojure.org/jira/browse/CLJ-1171

+0

आप उदाहरण भी कॉल कर सकते हैं? 2 से अधिक तर्कों के साथ: '(उदाहरण? स्ट्रिंग" ए "0)' -> 'सत्य' – Alex

+0

' (उदाहरण?स्ट्रिंग "ए" 0) 'ArityException त्रुटि – amirteymuri

उत्तर

8

दिलचस्प ... भले ही instance?core.clj में परिभाषित किया गया है, ऐसा लगता है वहाँ विशेष (instance?) रूपों के लिए clojure.lang.Compiler करने के लिए बनाया से निपटने है।

Compiler.java, line 3498:

if(fexpr instanceof VarExpr && ((VarExpr)fexpr).var.equals(INSTANCE)) 
     { 
     if(RT.second(form) instanceof Symbol) 
      { 
      Class c = HostExpr.maybeClass(RT.second(form),false); 
      if(c != null) 
       return new InstanceOfExpr(c, analyze(context, RT.third(form))); 
      } 
     } 

मैं व्याख्या मतलब है कि कि, जब आप संकलन/एक (instance?) प्रपत्र का मूल्यांकन, समारोह core.clj में परिभाषित हार्ड वायर्ड व्यवहार के पक्ष में नजरअंदाज कर दिया है, जो एक लापता व्याख्या करता है nil के रूप में दूसरा तर्क। मुझे लगता है कि यह प्रदर्शन के कारणों के लिए किया जाता है, इन-लाइनिंग के प्रकार के रूप में।

स्पष्ट रूप से यह विशेष हैंडलिंग केवल कुछ मामलों में लागू होती है (और मैं संकलक के साथ पर्याप्त परिचित नहीं हूं कि वे क्या हैं)। जैसा कि अंकुर के उत्तर से सचित्र है, instance? पर कॉल करने के तरीके हैं जो कार्य को core.clj में परिभाषित करने के कारण परिभाषित करते हैं।

+0

कंपाइलर (जो अभिव्यक्ति के उदाहरण को छोड़ देता है) में तेज़ पथ तब लिया जाता है जब कॉल एक प्रतीक के साथ सीधा कॉल होता है जो सीधे कक्षा को दर्शाता है। – Bendlas

+0

इसके लिए अभी टिकट है: http://dev.clojure.org/jira/browse/CLJ-1171 – Bendlas

2

आप instance? code को देखें, तो आपको लगता है कि विधि Class की isInstance कहा जाता है देखेंगे:

(def 
    ^{:arglists '([^Class c x]) 
     :doc "Evaluates x and tests if it is an instance of the class 
      c. Returns true or false" 
     :added "1.0"} 
    instance? (fn instance? [^Class c x] (. c (isInstance x)))) 

हुड के नीचे की तरह लग रहा है, nil (or false)x पैरामीटर के लिए डिफ़ॉल्ट मान के रूप में माना जाता है जब isInstance पर पास किया गया और यह false लौटाता है।

+1

देता है यह अकेले मनाए गए व्यवहार की व्याख्या करने में विफल रहता है, क्योंकि इस तरह से परिभाषित अन्य फ़ंक्शन तर्क की गलत संख्या के साथ बुलाए जाने पर धर्मार्थ अपवाद फेंकते हैं। – Alex

+0

आप सही हैं। मैंने इस फ़ंक्शन के अपने संस्करण के साथ परीक्षण नहीं किया है। मेरी गलती। और ऐसा लगता है कि यह "मुद्दा" क्लोजर 1.3 के बाद जारी है: https://groups.google.com/forum/?fromgroups=#!topic/clojure-dev/OmmqMyd_uXE –

+0

दिलचस्प। मैंने इस धागे द्वारा सुझाए गए टिकट की खोज की, और इसे नहीं मिला। मुझे लगता है कि यह तार के नीचे गिर गया है। मैं देखूंगा कि मैं एक नई बग रिपोर्ट कैसे सबमिट कर सकता हूं। यह असफल रहा, मुझे लगता है कि मैं उदाहरण लपेटूंगा? अभी के लिए। –

3

मुझे लगता है कि यह एक बग है। यदि आप उदाहरण के एक नए संस्करण को परिभाषित करते हैं ?, उदा।

(def 
^{:arglists '([^Class c x]) 
    :doc "Evaluates x and tests if it is an instance of the class 
     c. Returns true or false" 
    :added "1.0"} 
foo? (fn foo? [^Class c x] (. c (isInstance x)))) 

आप उम्मीद अपवाद

user=> (foo? String "bar") 
true 
user=> (foo? String 1) 
false 
user=> (foo? String) 
ArityException Wrong number of args (1) passed to: user$foo-QMARK- clojure.lang.AFn.throwArity (AFn.java:437) 
2

हम्म .... दिलचस्प ... सब नीचे कॉल विफल रहता है मिल जाएगा (जो कि यह कैसे माना जाता है है):

user=> (.invoke instance? String) 
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437) 

user=> (instance? (type "")) 
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437) 

user=> (apply instance? String []) 
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437) 

user=> (#'instance? Long) 
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437) 

इवेंट "उदाहरण" का एक नया उदाहरण बना रहा है? समारोह वस्तु काम करता है के रूप में यह काम करने के लिए माना जाता है:

user=> (def a (.newInstance (aget (.getConstructors (type instance?)) 0) (into-array []))) 
#'user/a 
user=> (a String) 
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437) 
user=> (a String "") 
true 
संबंधित मुद्दे