2011-07-28 6 views
6

मेरे पास एक कोड है जिसे मुझे eval के भीतर उपयोग करने की आवश्यकता है। कभी-कभी मुझे eval code से बाहर निकलना पड़ता है, लेकिन मेरी कोशिश त्रुटियों का कारण बनती है।ruby ​​- अंदर eval से कैसे वापस आना है?

उदा .:

# expected to see 1, 2 and 5; not 3 nor 4; and no errors 
eval "puts 1; puts 2; return; puts 3; puts 4" # => Error: unexpected return 
puts 5 

मैं return, end, exit, break साथ करने की कोशिश की, और मैं सफलता नहीं मिल सका। exit त्रुटियों उठाना नहीं है, लेकिन फिर मैं 5.

(ध्यान दें।: मुझे पता है कि eval बुराई है, लेकिन इस मामले में मैं इसे उपयोग करने की आवश्यकता) नहीं मिलता है

+0

मुझे कुछ अजीब पता चला। 'ब्रेक' 'उपज 'ब्लॉक से बाहर कूदता है। तो, मैं कर सकता हूं: 'def do_yield; प्राप्ति; समाप्त; do_yield {eval "1 रखता है; 2 डालता है; ब्रेक; 3 रखता है"}; 5' रखता है और मुझे अपेक्षित परिणाम मिलते हैं। मुझे नहीं पता कि यह क्यों काम करता है! –

उत्तर

4

आप सभी को धन्यवाद, लेकिन मैं एक समाधान मेरी समस्या में जो सबसे अच्छा फिट बैठता है पाया:

lambda do 
    eval "puts 1; puts 2; return; puts 3; puts 4" 
end.call 
puts 5 

इस तरह सहज ज्ञान युक्त return कीवर्ड eval अंदर इस्तेमाल किया जा सकता सफलतापूर्वक इसे से बाहर निकलने के लिए।

मुझे इस मामले में सशर्त-जैसे समाधान पसंद नहीं आया क्योंकि यह मुझे (या उपयोगकर्ता) को अंत में end जोड़ने के लिए मजबूर करेगा।

throw/catch या break का उपयोग करने के बारे में, मैं return कीवर्ड अधिक सहज ज्ञान युक्त मानता हूं।

2

तुम सिर्फ इस्तेमाल कर सकते हैं शुरुआती रिटर्न के बजाय सशर्त।

3

eval'd कोड बस इस जगह में चलाया जा रहा है। यह एक समारोह या ब्लॉक नहीं है। बिना eval के आप इसे कैसे करेंगे? शायद इस तरह:

puts 1 
puts 2 
if(conditionFor3And4) 
    puts 3 
    puts 4 
end 
3

आप नहीं कर सकते। आप विधियों से बाहर निकल सकते हैं, और ब्लॉक या लूप से बाहर तोड़ सकते हैं, लेकिन eval नहीं।

आप एक फेंक/कैच ब्लॉक बजाय

eval " 
    should_stop = true 
    catch :stop do 
    puts 1 
    puts 2 
    throw :stop if should_stop 
    puts 3 
    end 
" 

या इस कोशिश कर सकते:

should_stop = true 
    catch :stop do 
    eval " 
    puts 1 
    puts 2 
    throw :stop if should_stop 
    puts 3 
" 
end 

या सिर्फ एक सशर्त तरह Mchl कहा बस नहीं है, सशर्त रोक के बाद से आप शायद यह चाहते हैं, हमेशा, लेकिन फेंकने से आपको ब्लॉक से बाहर निकलने की सुविधा मिलती है इससे कोई फर्क नहीं पड़ता कि आप कितने स्तर नीचे हैं, जो इसे अधिक मजबूत बनाते हैं, अगर आपको नेस्टेड लूप से बाहर निकलना होगा या ऐसा कुछ।

+1

बहुत बढ़िया जवाब! इस तरह से मैं 'पकड़ सकता हूं: रोको ... अंत' __around__ 'eval' और केवल इसके अंदर 'फेंक' का उपयोग करें! आपके उत्तर से पहले, मैं 'निरंतरता' का उपयोग करने के बारे में सोच रहा था, लेकिन 'पकड़/फेंक' बहुत बेहतर है क्योंकि इसमें सीसी वैश्विक चर शामिल नहीं हैं, केवल प्रतीक हैं। –

+0

मुझे एहसास नहीं हुआ लेकिन यह अच्छा है, आप उन्हें eval ब्लॉक के बाहर रख सकते हैं। वाह। – loosecannon

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