2015-12-26 11 views
7

मेरे अस्पष्ट समझ है कि, रूबी 2.2 के स्ट्रिंग पर frozen विधि या रूबी 2.3 के frozen-string-literal: true pragma के साथ, एक प्रासंगिक जमे हुए स्ट्रिंग शाब्दिक प्रोग्राम निष्पादन यदि और केवल यदि स्ट्रिंग करता भर में केवल एक बार मूल्यांकन किया जाता है है इंटरपोलेशन नहीं है।एक जमे हुए स्ट्रिंग का मूल्यांकन

अंतर्वेशित नहीं

#frozen-string-literal: true 
5.times{p "".object_id} 

आउटपुट (समान वस्तु आईडी): निम्नलिखित वर्णन करने के लिए इस लगता है

70108065381260 
70108065381260 
70108065381260 
70108065381260 
70108065381260 

अंतर्वेशित

#frozen-string-literal: true 
5.times{p "#{}".object_id} 

आउटपुट (विभिन्न वस्तु मैं डी एस):

70108066220720 
70108066220600 
70108066220420 
70108066220300 
70108066220180 
  1. क्या इस संपत्ति (अर्थात, केवल एक बार मूल्यांकन किया जा रहा) कहा जाता है? यह अपरिवर्तनीयता से अलग होना चाहिए।
  2. क्या इस स्थिति की मेरी समझ है जब तारों को ऐसी संपत्ति सही होती है? इसका उल्लेख करते हुए आधिकारिक दस्तावेज कहां है?
  3. क्या इंटरपोलेटेड स्ट्रिंग को केवल एक बार मूल्यांकन करने का कोई तरीका है?

उत्तर

7
  1. Interning। स्ट्रिंग्स को इंटर्न किया जाता है।
  2. पूरी तरह से नहीं। यह अधिक है जैसे दुभाषिया यह तय कर सकता है कि स्ट्रिंग का मूल्य इसका मूल्यांकन करने से पहले क्या होगा। उदाहरण के लिए, विचार करें:

    5.times { puts "#{'foo'}".object_id } 
    

    आईडी समान है, भले ही इंटरपोलेशन शामिल है।

  3. नहीं। यह एक आंतरिक अनुकूलन है। Object#freeze का मुख्य बिंदु अपरिवर्तनीयता है।


अद्यतन: केवल शाब्दिक तार भली भाँति मिलता है। यह स्पष्ट है here

मुझे इंटरपोलेशन के लिए जिम्मेदार कोड का हिस्सा नहीं मिला। तो मुझे यकीन नहीं है कि "#{'foo'}" को शाब्दिक स्ट्रिंग माना जाता है। ध्यान दें कि जहां भी यह अनुवाद होता है, यह निचले पार्सर स्तर पर होता है और किसी भी वास्तविक प्रसंस्करण से पहले होता है। यह इस तथ्य से स्पष्ट है कि String#freeze को rb_str_freeze पर मैप किया गया है, जो opt_str_freeze पर कॉल नहीं करता है।

+0

आपका उत्तर 2. सही दिखता है, और रूबी का व्यवहार (आपका जवाब नहीं) मुझे भ्रमित कर रहा है। यह मामला कैसे हो सकता है कि "दुभाषिया तय कर सकता है" '# {'foo'} 'लेकिन' '{}' नहीं? उत्तरार्द्ध भी आसान है। – sawa

+1

@sawa, अभी भी सुनिश्चित नहीं है, कोड देखेंगे। मेरा अनुमान होगा कि वे बस '# {}" मामले को संभाल नहीं पाएंगे क्योंकि कोई भी इसका उपयोग नहीं करेगा। – ndn

+0

मुझे आपका जवाब पसंद है, लेकिन मैं आपके लिए या किसी और के लिए थोड़ा जवाब देना चाहता हूं 2. – sawa

-1

"फ्रोजन" इस बारे में नहीं है कि स्ट्रिंग का मूल्यांकन एक से अधिक बार किया जाता है या नहीं। यह है, आप सही हैं, mutability के बारे में।

एक स्ट्रिंग अक्षर का मूल्यांकन किया जाएगा, जिसमें हर बार लाइन का सामना करना पड़ता है।

इसे केवल एक बार मूल्यांकन करने के लिए (केवल) तरीका है, इसे एक स्रोत कोड की एक पंक्ति में डालना है जिसे केवल लूप में बजाय एक बार निष्पादित किया जाता है। एक लूप (या स्रोत कोड के किसी भी अन्य भाग) में एक स्ट्रिंग शब्दशः हमेशा मूल्यांकन किया जाएगा जब प्रोग्राम प्रवाह में स्रोत कोड की लाइन निष्पादित की जाती है।

यह वास्तव में एक अलग बात है कि यह जमे हुए/अपरिवर्तनीय है या नहीं, एक बार मूल्यांकन किया गया है।

स्वीकार्य उत्तर भ्रामक है। "यह अधिक है जैसे दुभाषिया यह तय कर सकता है कि स्ट्रिंग का मूल्य इसका मूल्यांकन करने से पहले क्या होगा।" नहीं। हर्गिज नहीं। इसे मूल्यांकन करने की जरूरत है। यदि स्ट्रिंग जमे हुए है, तो एक बार इसका मूल्यांकन होने के बाद, यह स्मृति में उसी स्थान का उपयोग करेगा और उसी ऑब्जेक्ट/object_id (जो एक ही चीज़ कहने के दो तरीके हैं) अन्य सभी समकक्ष तारों के रूप में। लेकिन अभी भी इंटरपोलेशन के साथ या बिना मूल्यांकन किया जा रहा है।

(इंटरपोलेशन के बिना, एक स्ट्रिंग अक्षर का 'मूल्यांकन' बहुत तेज़ है। सरल इंटरपोलेशन के साथ यह आमतौर पर बहुत तेज़ होता है। आप निश्चित रूप से एक महंगी विधि को कॉल करने के लिए इंटरपोलेशन का उपयोग कर सकते हैं, हालांकि, hypothetically)।

इंटरपोलेशन के बिना, मैं इसके बारे में चिंता नहीं करता। इंटरपोलेशन के साथ, यदि आपको लगता है कि आपका इंटरपोलेशन महंगा है तो आप इसे लूप में नहीं करना चाहते हैं - इसे टालने का एकमात्र तरीका लूप में ऐसा नहीं करना है, लेकिन लूप के बाहर एक बार स्ट्रिंग बनाएं।

रूबी दस्तावेज़ शायद "शाब्दिक स्ट्रिंग्स" के बजाय "स्ट्रिंग अक्षर" के बारे में बात करते हैं। ए "स्ट्रिंग शाब्दिक" स्रोत कोड में बाइट्स द्वारा बनाई गई कोई भी स्ट्रिंग है ('', "", %Q[], या रूबी में स्रोत कोड में स्ट्रिंग अक्षर बनाने के अन्य तरीकों का उपयोग करके)। इंटरपोलेशन के साथ या बिना।

तो स्ट्रिंग्स द्वारा बनाए गए किस प्रकार के स्ट्रिंग्स नहीं हैं? खैर, एक स्ट्रिंग उदाहरण के लिए फ़ाइल या नेटवर्क से बाइट्स में पढ़कर बनाई गई है। या मौजूदा स्ट्रिंग को लेकर एक विधि को कॉल करके बनाई गई स्ट्रिंग जो some_string.dup जैसी प्रतिलिपि लौटाती है। "स्ट्रिंग शाब्दिक" का अर्थ बाहरी इनपुट से पढ़ने के बजाय, स्रोत कोड में शाब्दिक रूप से बनाई गई स्ट्रिंग है। http://ruby-doc.org/core-2.1.1/doc/syntax/literals_rdoc.html

+1

ऑफक जमे हुए अपरिवर्तनीयता को संदर्भित करता है। ओपी ठंड के तारों के हिस्से के इंटर्निंग के बारे में पूछ रहा था। पार्सिंग है और रनटाइम मूल्यांकन है। [तर्क में कांटा रनटाइम मूल्यांकन से पहले होता है] (https://github.com/ruby/ruby/blob/22d8481f080ce4eb758803ad1f60273b6c3a10ad/compile.c#L4796), यही वह है जो मुझे दिमाग में था। इंटरपोलेशन के प्रदर्शन को प्रश्नों के साथ क्या करना है? दस्तावेज और कोड कहते हैं कि शाब्दिक तारों को प्रशिक्षित किया जाता है। यदि शाब्दिक स्ट्रिंग की आपकी परिभाषा सही है, तो इंटरपोलेशन के साथ एक बड़ी बग है ...इंटरपोलेशन सॉर्ट – ndn

+0

* "बाहरी इनपुट" * जोड़ता है क्योंकि इंटरपोलेटेड चीज कुछ भी हो सकती है। यहां महत्वपूर्ण बात स्थिर है। – ndn

+0

इंटरपोलेशन के साथ कोई बग नहीं है। उनमें से एक ही बाइट्स के साथ दो जमे हुए तारों में वही ऑब्जेक्ट_आईड होगा, वे वास्तव में एक स्ट्रिंग होंगे। इससे कोई फर्क नहीं पड़ता कि एक या दोनों तारों को इंटरपोलेशन के साथ बनाया गया था। यदि बाइट समान हैं, तो वे एक ही स्ट्रिंग हैं। यही "इंटर्निंग" का मतलब है। मुझे यकीन नहीं है कि मैं यहां भ्रम की प्रकृति को समझता हूं। एक स्ट्रिंग अक्षर एक कोड है जो स्रोत कोड में "उद्धरण चिह्न" (या समकक्ष) के साथ बनाया गया है चाहे वे इंटरपोलेशन का उपयोग करें या नहीं। यदि स्ट्रिंग शब्दशः के साथ नहीं बनाया गया स्ट्रिंग एक स्ट्रिंग अक्षर में इंटरपोलेट किया गया है। – jrochkind

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