2013-07-09 11 views
11

से गहरे लाल रंग का पाश पर अगले यह पाश लगाना आसान है अगले आइटम पर जाने के लिएकॉल रूबी में बाहरी विधि

(1..10).each do |a| 
    next if a.even? 
    puts a 
end 

परिणाम =>

1 
3 
5 
7 
9 

लेकिन क्या हुआ अगर मैं अगले बाहर से कॉल करने की आवश्यकता पाश की (जैसे: विधि)

def my_complex_method(item) 
    next if item.even? # this will obviously fail 
end 

(1..10).each do |a| 
    my_complex_method(a) 
    puts a 
end 

एकमात्र समाधान मैंने पाया और काम करता है throwउपयोग करने के लिए हैcatch की तरह में तो सवाल How to break outer cycle in Ruby?

def my_complex_method(item) 
    throw(:skip) if item.even? 
end 

(1..10).each do |a| 
    catch(:skip) do 
    my_complex_method(a) 
    puts a 
    end 
end 

मेरा प्रश्न है: किसी को भी किसी भी अधिक niftier समाधान यह करने के लिए मिल गया ?? या throw/catch ऐसा करने का एकमात्र तरीका है ??

इसके अलावा यदि मैं my_complex_method को केवल उस लूप (=> फेंक नहीं: छोड़ना) के हिस्से के रूप में कॉल करना चाहता हूं, तो क्या मैं किसी भी तरह से अपनी विधि को बता सकता हूं जिसे इसे लूप से बुलाया जाता है?

+2

आप वास्तव में, * वास्तव में * सोचने पर हैं। एक मूल्य वापस करें और लौटे हुए मूल्य के आधार पर 'अगली' सशर्त रूप से आमंत्रित करें। सॉफ्टवेयर में यह एक * अविश्वसनीय रूप से * सामान्य पैटर्न है, जिसकी मैंने कभी भी उपयोग की है। 'फेंक'/'पकड़ 'के पास कोई जगह नहीं है। – meagar

+0

मैं मानता हूं कि इस उदाहरण के लिए यह हास्यास्पद है, लेकिन मेरे पास एक ऐसा मामला है जहां मुझे लूप और विधि – equivalent8

उत्तर

12

आप जटिल विधि एक बूलियन लौटा सकता है, और उसके बाद आप इस तरह अपने पाश पर तुलना:

def my_complex_method(item) 
    true if item.even? 
end 

(1..10).each do |a| 
    next if my_complex_method(a) 
    puts a 
end 

एक साधारण दृष्टिकोण है, लेकिन कोशिश पकड़ से अलग।

अद्यतन

के रूप में पहले से ही item.even? एक बूलियन मान लौटने के लिए, आप true if item.even? भाग की जरूरत नहीं है, आप के रूप में पालन कर सकते हैं:

def my_complex_method(item) 
    item.even? 
end 
+0

को अलग करने की आवश्यकता है, मैं इस उत्तर के साथ जाऊंगा क्योंकि इससे मुझे एहसास हुआ कि मेरे असली कोड में 'my_complex_method' अलग-अलग तरीके से लिखा जा सकता है यह हासिल किया जा सकता है (साथ ही साथ मेरे प्रश्न पर मीगर टिप्पणी भी) ... लेकिन अगर किसी को कभी भी मेरे क्वेशियन में वर्णित कार्यक्षमता का उपयोग करने की आवश्यकता है तो मैं [प्राइटिस उत्तर] के साथ जाऊंगा (http://stackoverflow.com/a/17546856/473040) मेरे 'थ्रो/कैच' समाधान – equivalent8

1

Enumerator#next और Enumerator#peek goo के लिए अच्छा विकल्प हो जाएगा :

def my_complex_method(e) 
    return if e.peek.even? 
    p e.peek 
end 
enum = (1..5).each 
enum.size.times do |a| 
    my_complex_method(enum) 
    enum.next 
end 

आउटपुट

1 
3 
5 
0

आप सभी की जरूरत आप प्रगणक बुद्धिमानी से इस्तेमाल कर सकते हैं my_complex_method द्वारा दिए गए मान के आधार पर, मूल्यों का केवल कुछ से कार्यवाही करने के है:

(1..10).map { |a| [a, my_complex_method(a)] }.each do |a, success| 
    puts a if success 
end 
आप विधि को स्वीकार ब्लॉक निर्धारित कर सकते हैं और सफलता या विफलता के आधार पर इस ब्लॉक में कुछ कार्रवाई करें: (1..10)। प्रत्येक करें | ए | my_complex_method {| सफलता | अगली अगर सफलता} अंत स्कॉइंग करने के लिए धन्यवाद, आप 'पकड़'/`फेंक 'का उपयोग नहीं कर पा रहे हैं, और प्रोसेसिंग स्थिति के आधार पर' अगली 'कॉल कर सकते हैं।
+0

के मुकाबले जहां तक ​​मैं पहली विधि बता सकता हूं, काम नहीं करता है - 'अगली'' प्रत्येक ' –

+0

आह से गुजरती नहीं है, आप सही हैं - - 'अगला' यहां 'my_complex_method' में परिभाषित उपज को संदर्भित करता है ... – samuil

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