2009-06-30 10 views
17

में लागू वापसी मूल्य रूबी के लिए कुछ हद तक नया है और हालांकि मुझे यह बहुत ही सहज ज्ञान युक्त भाषा मिलती है, मुझे समझ में कुछ कठिनाई हो रही है कि कैसे अंतर्निहित वापसी मूल्य व्यवहार करते हैं।रुबी

मैं टॉमकैट लॉग को grep करने के लिए एक छोटे से प्रोग्राम पर काम कर रहा हूं और प्रासंगिक डेटा से पाइप-सीमांकित सीएसवी फाइलें उत्पन्न करता हूं। यहां एक सरलीकृत उदाहरण दिया गया है जिसका उपयोग मैं लॉग एंट्री से लाइनें उत्पन्न करने के लिए कर रहा हूं।

class LineMatcher 
    class << self 
    def match(line, regex) 
     output = "" 
     line.scan(regex).each do |matched| 
     output << matched.join("|") << "\n" 
     end 
     return output 
    end   
    end 
end 


puts LineMatcher.match("00:00:13,207 06/18 INFO stateLogger - TerminationRequest[[email protected][accountNumber=0951714636005,srNumber=20]", 
         /^(\d{2}:\d{2}:\d{2},\d{3}).*?(\d{2}\/\d{2}).*?\[accountNumber=(\d*?),srNumber=(\d*?)\]/) 

मुझे इस कोड को चलाने मैं निम्नलिखित है, जो है क्या उम्मीद है जब स्पष्ट रूप से उत्पादन के मूल्य में लौटने वापस मिलता है।

00:00:13,207|06/18|0951714636005|20 

हालांकि, अगर मैं निम्नलिखित करने के लिए LineMatcher बदल सकते हैं और स्पष्ट रूप से नहीं लौटते उत्पादन:

class LineMatcher 
     class << self 
     def match(line, regex) 
      output = "" 
      line.scan(regex).each do |matched| 
      output << matched.join("|") << "\n" 
      end 
     end   
     end 
    end 

तो मैं निम्नलिखित परिणाम प्राप्त:

00:00:13,207 
06/18 
0951714636005 
20 

जाहिर है, यह नहीं है वांछित परिणाम। ऐसा लगता है कि मुझे आउटपुट वैरिएबल से छुटकारा पाने में सक्षम होना चाहिए, लेकिन यह अस्पष्ट है कि रिटर्न वैल्यू कहां से आ रहा है। इसके अलावा, पठनीयता के लिए कोई अन्य सुझाव/सुधार स्वागत है।

+0

सही प्रारूपण – csamuel

उत्तर

23

माणिक में कोई भी बयान पिछले का मूल्यांकन अभिव्यक्ति का मान देता है । आपको यह जानने के लिए कि आपका प्रोग्राम कैसे कार्य करेगा, आपको सबसे अधिक उपयोग की जाने वाली विधि के कार्यान्वयन और व्यवहार को जानने की आवश्यकता है।

#each आपके द्वारा पुनरारंभ किए गए संग्रह को लौटाता है। उस ने कहा, निम्नलिखित कोड line.scan (regexp) के मान को वापस कर देगा।

line.scan(regex).each do |matched| 
    output << matched.join("|") << "\n" 
end 

आप निष्पादन का परिणाम वापस करना चाहते हैं, तो आप map, जो each के रूप में काम करता है लेकिन संशोधित संग्रह रिटर्न उपयोग कर सकते हैं।

class LineMatcher 
    class << self 
    def match(line, regex) 
     line.scan(regex).map do |matched| 
     matched.join("|") 
     end.join("\n") # remember the final join 
    end   
    end 
end 

कई उपयोगी तरीकों से आप अपने बहुत ही विशेष मामले के आधार पर उपयोग कर सकते हैं कर रहे हैं। इस में आप inject का उपयोग करना चाहेंगे जब तक कि scan द्वारा लौटाए गए परिणामों की संख्या अधिक न हो (सरणी पर काम करना, फिर उन्हें विलय करना एक स्ट्रिंग पर काम करने से अधिक कुशल है)।

class LineMatcher 
    class << self 
    def match(line, regex) 
     line.scan(regex).inject("") do |output, matched| 
     output << matched.join("|") << "\n" 
     end 
    end   
    end 
end 
+2

फीडबैक के लिए धन्यवाद ... मुझे लगता है कि मेरा भ्रम इस तथ्य से हुआ कि यह कहना मुश्किल था कि वास्तव में आखिरी बयान के रूप में क्या व्याख्या की जाती है। – csamuel

13

रूबी में एक विधि का वापसी मूल्य अंतिम विवरण द्वारा दिया गया मूल्य है। आप भी एक स्पष्ट वापसी का विकल्प चुन सकते हैं।

आपके उदाहरण में, पहला स्निपेट स्ट्रिंग output देता है। दूसरा स्निपेट हालांकि each विधि (जो अब अंतिम स्टैमेट है) द्वारा लौटाया गया मान देता है, जो मैचों की सरणी बन जाता है।

irb(main):014:0> "StackOverflow Meta".scan(/[aeiou]\w/).each do |match| 
irb(main):015:1* s << match 
irb(main):016:1> end 
=> ["ac", "er", "ow", "et"] 

अपडेट: हालांकि यह अभी भी एक ही लाइन पर आपके आउटपुट की व्याख्या नहीं करता है। मुझे लगता है कि यह एक स्वरूपण त्रुटि है, इसे प्रत्येक मैच को एक अलग पंक्ति पर मुद्रित करना चाहिए क्योंकि यह puts एक सरणी प्रिंट करता है। एक छोटी सी कोड यह मेरे से बेहतर व्याख्या कर सकते हैं ..

irb(main):003:0> one_to_three = (1..3).to_a 
=> [1, 2, 3] 
irb(main):004:0> puts one_to_three 
1 
2 
3 
=> nil 

व्यक्तिगत तौर पर मैं (इस मामले में) स्पष्ट वापसी अधिक पठनीय के साथ अपने विधि को खोजने के

+1

क्षमा करें, हाँ, मेरे पास स्वरूपण त्रुटि थी। प्रश्न में सुधार हुआ। – csamuel