2010-02-17 11 views
5

मैं बेहतर रूबी समझने की कोशिश कर पर काम कर रहा है और यहां के भीतर एक वैश्विक सेटिंग के कुछ मैं कुछ समस्या आ रही है:एक proc

$SAFE = 1 
puts $SAFE # 1 
proc { 
    $SAFE = 2 
    puts $SAFE # 2 
}.call 
puts $SAFE # 1 

ऊपर कोड आंशिक रूप से ERB के स्रोत बेहतर उजागर करने के लिए फिर से लिखा से लिया जाता है उदाहरण। मूल रूप से proc के भीतर $SAFE का मान निर्धारित कर सकता है कि जो भी मूल्य चाहता है और proc के बाद, SAFE का मान वापस प्रोसेस से पहले वापस लौटाता है।

, तो इसके बजाय शब्द $SAFE मैं एक अलग शब्द के लिए इसे बदल, इस तरह के रूप $DOOR का उपयोग करने का:

$DOOR = 1 
puts $DOOR 
proc { 
    $DOOR = 2 
    puts $DOOR 
}.call 
puts $DOOR 

तो proc के बाद $DOOR का मूल्य 2 और नहीं 1. क्यों दोनों के बीच अंतर उदाहरण?

उत्तर

11

यह बल्कि एक सरल, वास्तव में: कारण $SAFE ऐसा व्यवहार नहीं करता है जैसे आप वैश्विक चर से अपेक्षा करते हैं क्योंकि यह वैश्विक चर नहीं है। यह एक जादू यूनिकॉर्न चीज़ है।

रुबी में उन जादू यूनिकॉर्न चीज़ों में से कुछ हैं, और दुर्भाग्यवश दुर्भाग्यवश बहुत अच्छी तरह से प्रलेखित नहीं हैं (वास्तव में सभी दस्तावेजों पर नहीं, क्योंकि वैकल्पिक रूबी कार्यान्वयन के डेवलपर्स मुश्किल तरीके से पाए गए हैं। ये चीजें सभी अलग-अलग व्यवहार करती हैं और (प्रतीत होता है) असंगत रूप से, और उनमें से केवल दो चीजें आम हैं, वे वैश्विक चर की तरह दिखते हैं लेकिन उनके जैसा व्यवहार नहीं करते हैं।

कुछ के पास स्थानीय दायरा है। कुछ धागे-स्थानीय दायरे हैं। कुछ लोग कभी भी उन्हें असाइन किए बिना किसी जादूगर रूप से बदल जाते हैं। कुछ के पास दुभाषिया के लिए जादू का अर्थ है और भाषा कैसे व्यवहार करती है बदलती है। कुछ लोगों के साथ जुड़े अन्य अजीब अर्थशास्त्र हैं।

$SAFE में लगभग सभी उपरोक्त हैं: यह थ्रेड-लोकल है, जिसका अर्थ है कि यदि आप इसे एक थ्रेड में बदलते हैं, तो यह अन्य धागे को प्रभावित नहीं करता है। यह स्थानीय है, जिसका अर्थ है कि यदि आप इसे स्थानीय दायरे में बदलते हैं (जैसे कक्षा, मॉड्यूल, विधि या ब्लॉक), यह बाहरी दायरे को प्रभावित नहीं करता है (जैसा आपने पाया है)।इसका अर्थ दुभाषिया के लिए जादू का अर्थ है, क्योंकि इसे 0 से अलग मान पर सेट करने से कुछ चीजें काम नहीं करती हैं। और इसमें अतिरिक्त अजीब अर्थशास्त्र है कि आप केवल बढ़ा सकते हैं, इसकी कीमत, कम करें।

+0

ठीक है, वही है जो मैं जानना चाहता था। मैं स्थिरता की तलाश कर रहा था और उम्मीद कर रहा था, लेकिन इसके बजाय मुझे लगता है कि हम एक जादू यूनिकॉर्न चीज़ के साथ काम कर रहे हैं। :-) – Francois

3

मुझे नहीं पता कि $ SAFE इस तरह से क्यों काम कर रहा है, लेकिन मुझे पता है कि यह एक पूर्वनिर्धारित वैश्विक चर है जो जादूगर बाहरी डेटा और धागे से संबंधित जादू का अर्थ है।

तो इसे प्रोग्राम ऑब्जेक्ट के रूप में उपयोग न करें।

देखें http://ruby-doc.org/docs/ProgrammingRuby/html/taint.html

यह नहीं, btw, एक काम के साथ $ सुरक्षित का मूल्य कम करने के लिए संभव होना चाहिए, लेकिन यह निष्पादन संदर्भ और एक बहु कार्यक्रम से जुड़ा हुआ है, उदाहरण के लिए, कई हो सकता है विभिन्न धागे में $ SAFE मूल्य ...

+0

मैंने कलंक सामग्री पर पढ़ा और मुझे लगता है कि $ SAFE एक पूर्वनिर्धारित वैश्विक चर है। लेकिन मुझे समझ में नहीं आता कि क्यों पूर्वनिर्धारित वैश्विक युद्ध अन्य वैश्विक युद्धों से अलग व्यवहार करते हैं। – Francois

+1

कारण वैरिएबल द्वारा भिन्न होता है, $ SAFE के मामले में ऐसा इसलिए होता है क्योंकि पूरा बिंदु परावर्तक की एक तरफा वृद्धि करना है। अगर $ SAFE असाइनमेंट के माध्यम से घट सकता है, इंजेक्शन कोड में केवल $ SAFE को असाइनमेंट शामिल किया जा सकता है। – DigitalRoss

1

$DOOR का मान 2 होना चाहिए। क्योंकि $DOOR वैश्विक चर को 1 से 2 तक पुन: प्रारंभ किया गया है। Global Variables पर अधिक जानकारी।

$SAFE$SAFE चर सेट करके सुरक्षित स्तर। डिफ़ॉल्ट रूप से यह शून्य पर सेट है।

और proc भीतर $SAFE .Hence उस पर और अधिक प्रदर्शित मूल्य यानी पहले से निर्धारित 1. जांच है दायरे के अंत तक याद में एक नहीं होगा इस here और भी docs

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