2010-10-31 15 views
24

मैं यह जांचना चाहता हूं कि दो संदर्भ एक ही वस्तु को इंगित करते हैं या नहीं। यह मैं बसमुझे पर्ल संदर्भों की तुलना कैसे करनी चाहिए?

if ($ref1 == $ref2) { 
# cheap numeric compare of references 
print "refs 1 and 2 refer to the same thing\n"; 
} 

उपयोग कर सकते हैं के रूप में perlref में उल्लेख किया है लगता है, लेकिन मैं थोड़ा ही उद्देश्य के लिए कुछ समारोह के उपयोग को देख याद है। क्या कोई कारण है कि मुझे सरल संख्यात्मक समानता परीक्षण का उपयोग नहीं करना चाहिए?

नोट मैं केवल यह जानना चाहता हूं कि संदर्भ सटीक उसी वस्तु को इंगित करते हैं या नहीं। मैं ऑब्जेक्ट की सामग्री की तुलना करने का कोई तरीका नहीं ढूंढता हूं।

उत्तर

23

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

हालांकि, आपके द्वारा दिखाए गए स्निपेट में, आपको पहले यह सुनिश्चित करना होगा कि $ref1 और $ref2 दोनों वास्तव में संदर्भ हैं। अन्यथा आपको संदर्भ पतों वाले नियमित स्केलर के कारण गलत परिणाम मिल सकते हैं।

इसके अलावा, कुछ भी उनके पते को सूचित करने के संदर्भों की गारंटी नहीं देता है। ऑब्जेक्ट्स, उदाहरण के लिए, वे अलग-अलग संदर्भों में लौटने वाले मूल्य को प्रभावित करने के लिए ओवरलोडिंग का उपयोग कर सकते हैं।

संख्यात्मक समानता के लिए सीधे संदर्भों की तुलना करने का एक और ठोस तरीका फ़ंक्शन का उपयोग Scalar::Util द्वारा किया गया है, यह सुनिश्चित करने के बाद कि दोनों पक्ष वास्तव में संदर्भ हैं।

+1

यदि आप किसी वर्ग का उपयोग कर रहे हैं जिनके ऑब्जेक्ट्स में एक nummification ('0 +') अधिभार है, या '==' अधिभार (शायद '<=>' के माध्यम से), तो यह संभव है कि आप वास्तव में * इसके * अवरुद्ध, कस्टम समानता की भावना। उन विचारों का जिक्र किए बिना कंबल स्टेटमेंट बनाना बेहद मुश्किल लगता है। उस ने कहा, मैं कई परिदृश्यों के बारे में नहीं सोच सकता जहां मॉड्यूल के फ़ंक्शन द्वारा लिया गया कोड पथ एक महत्वपूर्ण पथ होगा जिसे आप प्रदर्शन के हर अंतिम बिट को लिखने की कोशिश कर रहे हैं। लेकिन अगर यह था, तो निश्चित रूप से आप एक सामान्य '==' का उपयोग करना चाहते हैं। – tchrist

+0

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

+0

यह भी एक विशिष्ट उत्तर के लायक है। यही कारण है कि आप मेरा अपवित्र हो गया। ☺ – tchrist

15

समारोह आप देख रहे हैं Scalar::Util से refaddr है (कि मूल्यों तुलना की जा रही सुनिश्चित करने के बाद वास्तव में संदर्भ हैं):

use Scalar::Util 'refaddr'; 

if ($obj1 and ref($obj1) and $obj2 and ref($obj2) and 
    refaddr($obj1) == refaddr($obj2)) 
{ 
    # objects are the same... 
} 
+2

'सीपीएन/लिस्ट-यूटिल/लिब/स्केलर/यूटिल/पीपीपीएम' के रेफैडर() द्वारा किए गए असाधारण उपाय, दिग्गज के वास्तविक पते को दिव्य करने के लिए केवल आशीर्वाद() फ़ंक्शन के उपायों से अधिक होते हैं पैकेज का नाम। – tchrist

+4

सौभाग्य से, लिस्ट-यूटिल वितरण के रूप में, और स्केलर :: इसमें मॉड्यूल का उपयोग करने के लिए कोर मॉड्यूल हैं, और कोर एक सी कंपाइलर के साथ बनाया गया है, बहुत से लोग स्केलर के सी संस्करण का उपयोग करने की लक्जरी हो जाते हैं :: Util :: refaddr, जो कि केवल एक ही ध्वज जांच और एक dereference है। – rafl

+0

वास्तव में mktables कोड में एक परीक्षण है कि यह एक तेज स्केलर :: उपयोग या नहीं है। मुझे याद रखना चाहिए था कि यह सिर्फ एक सी कॉल हो सकता है। एक कोड स्निपेट प्रदान करने वाले एकमात्र उत्तर के लिए – tchrist

7

मुझे यह मानना ​​है कि आपका #comment कितना सस्ता (= तेज़) समानता परीक्षण एक कारण के लिए था। यह देखते हुए, आपको शायद सस्ते समानता परीक्षण का उपयोग करना चाहिए। यह बहुत तेज है, eq से बहुत तेज है, किसी भी प्रकार की तुलना की तुलना में अकेले रहने दें।

यह संभव है कि सीधे या परोक्ष रूप से अधिभारित == ऑपरेटर वाला ऑब्जेक्ट अपने उद्देश्यों के लिए परीक्षण का उपयोग कर सके। लेकिन अगर यह ऐसा कर रहा है, तो आप इसके मध्यस्थ उत्तर को भी पसंद कर सकते हैं ..

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

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

जब तक आप ओवरलोडिंग चिंताओं को समझते हैं, तो यह समझने की गलती है कि एक दृष्टिकोण सही है और दूसरा गलत है। प्रत्येक का उद्देश्य है। यदि आप जो भी कर रहे हैं वह करना हमेशा गलत होता है, तो उस ऑपरेशन को या तो प्रतिबंधित किया जाएगा या कम से कम चेतावनी दी जाएगी।

आप ध्यान दें कि यह इतना चिह्नित है।

+1

आपको लगता है कि सभी डाउन-मतदाताओं के पास वास्तव में यह कहने की तंत्रिका होगी कि वे क्या सोचते हैं कि मैंने कहा है कि यह गलत है। लेकिन वे नहीं करते हैं। तो स्पष्ट रूप से वे अज्ञात छिपे हुए पॉट-शॉट्स को तर्कसंगत भाषण में पसंद करते हैं। यदि आप अपने वोट को उचित नहीं ठहरा सकते हैं, तो शायद आपको इसे नहीं बनाना चाहिए। – tchrist

+1

मुझे आपके द्वारा पोस्ट की गई कोई समस्या नहीं है (और डाउनवोट नहीं किया गया है) लेकिन मुझे लगता है कि यह दिलचस्प है कि कई पोस्टर डाउनवॉट्स के लिए स्पष्टीकरण मांगते हैं लेकिन अपवॉट के लिए नहीं। मैं हर दिन देने वाले 20-विषम अपवॉट्स को न्यायसंगत बनाने में समय नहीं लगाता हूं। – friedo

+3

@friedo: अगर आपको लगता है कि मैं सही हूं, तो यह जानना पर्याप्त है कि आपको लगता है कि मैं सही हूं। (यहां तक ​​कि, यदि कोई विशेष बिंदु पर जोर देने योग्य है, तो "+1 के लिए ..." टिप्पणियां काफी आम हैं।) अगर आपको लगता है कि मैं गलत हूं, तो मुझे पता होना चाहिए कि क्यों * आपको लगता है कि मैं गलत हूं इसलिए मैं या तो मेरे बयान को स्पष्ट कर सकते हैं, अपने आपत्तियों का खंडन कर सकते हैं, या यहां तक ​​कि यहां तक ​​कि (भयावहता का डरावना) महसूस कर सकते हैं कि आपके आपत्तियां सटीक हैं और उनसे कुछ सीखती हैं। यही कारण है कि, कम से कम, डाउनवॉट्स पर टिप्पणियां चाहते हैं लेकिन अपवॉट्स के लिए किसी भी तरह से परवाह नहीं करते हैं। –

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