2012-03-28 11 views
7

एक विधि $ सुरक्षित = 4 के साथ एक धागा द्वारा कहा जाता है, तो उस विधि में एक ही $ सुरक्षित स्तर के साथ चलाया जाता है:

def test_method 
    raise "value of $SAFE inside the method: #{$SAFE}" 
end 
t = Thread.new{$SAFE = 4; self.test_method}; t.join 
=> RuntimeError: value of $SAFE inside the method: 4 

हालांकि, जब एक ब्लॉक कहा जाता है, यह से $ सुरक्षित उपयोग करने के लिए लगता है इसके मूल संदर्भ के बजाय:

test_lambda = lambda do 
    raise "value of $SAFE inside the lambda: #{$SAFE}" 
end 
t = Thread.new{$SAFE = 4; test_lambda.call}; t.join 
=> RuntimeError: value of $SAFE inside the lambda: 0 

क्या कोई यह समझा सकता है कि यह इस तरह क्यों काम करता है? यह एक सुरक्षा समस्या की तरह लगता है।

(कारण मैं puts के बजाय raise उपयोग कर रहा हूँ कि puts $ सुरक्षित में काम नहीं करता है = 4)

यह एक उचित रूप में सुरक्षित संदर्भ में एक दागी स्ट्रिंग eval के लिए इस्तेमाल किया जा सकता है:

test_lambda = lambda{|s| puts "Tainted: #{s.tainted?}"; eval s} 
t = Thread.new{$SAFE = 4; test_lambda.call("puts `date`")}; t.join 
=> Tainted: true 
=> Fri Mar 30 03:15:33 UTC 2012 
+0

परिभाषा के समय मूल्य को बंद करने के लिए बंद नहीं होगा? –

+1

क्या आप ब्लॉक के भीतर कार्रवाइयां निष्पादित करने में सक्षम हैं कि '$ SAFE' स्तर 0 की अनुमति होगी? –

+1

एंड्रयू: हाँ। लैम्ब्डा की सामग्री को 'रखता \' होस्टनाम \ 'के साथ कुछ बदलकर इसे सुरक्षित रूप से $ SAFE = 4 थ्रेड के भीतर करने का कारण बनता है। मैं इस व्यवहार को एक दायरे परिप्रेक्ष्य (थोड़े) से समझता हूं - मैं बस सोच रहा हूं कि इस संबंध में $ SAFE पूरी तरह से टूट गया है या नहीं। – rcrogers

उत्तर

5

यह क्योंकि एक लैम्ब्डा गुंजाइश यह (सभी स्थानीय चर सहित!)

इसलिए में परिभाषित किया गया था के साथ चल रही है, तो आप सुरक्षित स्तर 0 पर लैम्ब्डा परिभाषित, और यह इसलिए उस स्तर पर क्रियान्वित जब इसे कहा जाता था, वैरिएबल की स्थिति यही थी।

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