दिलचस्प पोस्ट
अजगर में मटप्ललिब के साथ प्लॉट लॉगरिदमिक कुल्हाड़ियों एएसपी.नेट की छिपी हुई विशेषताओं मैं अजगर कोड लाइन-बाय-लाइन कैसे प्रोफ़ाइल कर सकता हूं? स्विफ्ट में कैसे सेटअप पुश नोटिफिकेशन वेब एप्लिकेशन से एसएमएस स्ट्रिंग में पायथन के अंदर मैं एक वैरिएबल कैसे डालूं? एक आसान तरीके से लॉगिंग में त्रुटि 301 सभी स्थानों को हाइफ़ोनों को बदलने के लिए रीडायरेक्ट करें एंड्रॉइड में गेम क्लायंट शुरू कर रहा है PHP (MySQL) त्रुटि: "चेतावनी: mysql_num_rows () पैरामीटर 1 संसाधन होने की उम्मीद" यूटीएफ -8 सभी तरह से माध्यम से क्या ऑप्शन शब्दकोश कुंजी में कुंजीपटल प्रदर्शित करता है? किसी भी वर्ण से मिलान करने के लिए नियमित अभिव्यक्ति 10 बार से अधिक दोहराई जा रही है Xcode 6 iPhone सिम्युलेटर आवेदन समर्थन स्थान कोनेर एनजी-व्यू / राउटिंग फोनगैप में काम नहीं कर रहा है

रूबी में ब्लॉक और पैदावार

मैं ब्लॉकों और yield समझने की कोशिश कर रहा हूं और रूबी में कैसे काम करता हूं।

yield कैसे उपयोग किया जाता है? बहुत से रेल अनुप्रयोगों को मैंने एक अजीब तरह से उपयोग yield में देखा है।

क्या कोई मुझे बता सकता है या मुझे बता सकता है कि उन्हें समझने के लिए कहां जाना है?

वेब के समाधान से एकत्रित समाधान "रूबी में ब्लॉक और पैदावार"

हां, यह पहली बार में थोड़ी परेशानी है

रूबी में, कोड के मनमानी खंड को चलाने के लिए तरीकों को एक कोड ब्लॉक प्राप्त हो सकता है।

जब किसी विधि को एक ब्लॉक की उम्मीद होती है, तो यह yield फंक्शन को कॉल करके इसे आमंत्रित करता है।

यह बहुत आसान है, उदाहरण के लिए, एक सूची पर पुनरावृत्त करने के लिए या कस्टम एल्गोरिदम प्रदान करने के लिए

निम्नलिखित उदाहरण लें:

मैं किसी Person नाम के साथ शुरू किया गया एक Person वर्ग को परिभाषित करने जा रहा हूं और एक do_with_name विधि प्रदान करता do_with_name जो कि जब लाया जाता था, तो केवल name विशेषता को ही प्राप्त होगा, ब्लॉक प्राप्त करने के लिए।

 class Person def initialize( name ) @name = name end def do_with_name yield( @name ) end end 

इससे हमें उस विधि को कॉल करने और एक मनमाना कोड ब्लॉक पास करने की अनुमति मिल जाएगी।

उदाहरण के लिए, नाम प्रिंट करने के लिए हम करेंगे:

 person = Person.new("Oscar") #invoking the method passing a block person.do_with_name do |name| puts "Hey, his name is #{name}" end 

मुद्रित होगा:

 Hey, his name is Oscar 

नोटिस, ब्लॉक प्राप्त करता है, एक पैरामीटर के रूप में, एक चर नामक name (NB आप इस चर को जो कुछ भी पसंद कर सकते हैं उसे कॉल कर सकते हैं, लेकिन इसे name देने में समझ में आता है)। जब कोड yield आह्वान करता yield तो यह पैरामीटर को @name के मान के साथ भरता है

 yield( @name ) 

हम एक अलग कार्रवाई करने के लिए एक और ब्लॉक प्रदान कर सकते हैं उदाहरण के लिए, नाम उल्टा करें:

 #variable to hold the name reversed reversed_name = "" #invoke the method passing a different block person.do_with_name do |name| reversed_name = name.reverse end puts reversed_name => "racsO" 

हमने उसी विधि ( do_with_name ) का इस्तेमाल किया – यह सिर्फ एक अलग ब्लॉक है

यह उदाहरण तुच्छ है अधिक दिलचस्प उपयोग एक सरणी में सभी तत्वों को फ़िल्टर करना है:

  days = ["monday", "tuesday", "wednesday", "thursday", "friday"] # select those which start with 't' days.select do | item | item.match /^t/ end => ["tuesday", "thursday"] 

या, हम एक कस्टम सॉर्ट एल्गोरिथ्म भी प्रदान कर सकते हैं, उदाहरण के लिए स्ट्रिंग आकार के आधार पर:

  days.sort do |x,y| x.size <=> y.size end => ["monday", "friday", "tuesday", "thursday", "wednesday"] 

मुझे उम्मीद है कि इससे आपको बेहतर समझने में मदद मिलेगी।

बीटीडब्लू, यदि ब्लॉक वैकल्पिक है तो आपको इसे इस तरह कॉल करना चाहिए:

 yield(value) if block_given? 

यदि वैकल्पिक नहीं है, तो बस इसे खोलें।

यह काफी संभव है कि कोई सही मायने में विस्तृत उत्तर प्रदान करेगा, लेकिन मैं हमेशा रॉबर्ट सोसिंस्की से इस पोस्ट को ब्लॉक, प्रोसेस और लैम्ब्डा के बीच सूक्ष्मता का एक महान स्पष्टीकरण प्राप्त करने के लिए मिला है।

मुझे यह जोड़ना चाहिए कि मेरा मानना ​​है कि जिस पोस्ट को मैं लिंक कर रहा हूं वह विशिष्टता 1.8 है। कुछ चीजें रूबी 1.9 में बदल दी गई हैं, जैसे कि ब्लॉक वेरिएबल ब्लॉक में स्थानीय है। 1.8 में, आपको निम्न की तरह कुछ मिलेगा:

 >> a = "Hello" => "Hello" >> 1.times { |a| a = "Goodbye" } => 1 >> a => "Goodbye" 

जबकि 1.9 आपको देगा:

 >> a = "Hello" => "Hello" >> 1.times { |a| a = "Goodbye" } => 1 >> a => "Hello" 

मेरे पास इस मशीन पर 1.9 नहीं है, इसलिए उपर्युक्त में त्रुटि हो सकती है।

रुबी में, तरीकों को यह देखने की जांच हो सकती है कि क्या उन्हें इस तरह से बुलाया गया था कि सामान्य तर्कों के अलावा एक ब्लॉक प्रदान किया गया था। आम तौर पर यह block_given? का उपयोग किया जाता है block_given? विधि लेकिन आप अंतिम तर्क नाम से पहले एक एम्पर्ससंड ( & ) को प्रीफ़िक्स करके ब्लॉक को एक स्पष्ट प्रक्रिया के रूप में भी देख सकते हैं

यदि किसी विधि को एक ब्लॉक के साथ लागू किया जाता है तो विधि कुछ तर्कों के साथ ब्लॉक (ब्लॉक कॉल) को नियंत्रित कर सकती है, यदि आवश्यक हो इस उदाहरण पद्धति पर विचार करें जो दर्शाता है:

 def foo(x) puts "OK: called as foo(#{x.inspect})" yield("A gift from foo!") if block_given? end foo(10) # OK: called as foo(10) foo(123) {|y| puts "BLOCK: #{y} How nice =)"} # OK: called as foo(123) # BLOCK: A gift from foo! How nice =) 

या, विशेष ब्लॉक तर्क वाक्यविन्यास का उपयोग कर:

 def bar(x, &block) puts "OK: called as bar(#{x.inspect})" block.call("A gift from bar!") if block end bar(10) # OK: called as bar(10) bar(123) {|y| puts "BLOCK: #{y} How nice =)"} # OK: called as bar(123) # BLOCK: A gift from bar! How nice =) 

मैं एक तरह से जोड़ना चाहता था कि आप पहले से ही महान जवाबों के लिए ऐसा क्यों करते हैं

पता नहीं कि आप किस भाषा से आ रहे हैं, लेकिन मानते हुए यह एक स्थैतिक भाषा है, इस तरह की चीज़ परिचित दिखाई जाएगी इस तरह आप जावा में एक फ़ाइल पढ़ते हैं

 public class FileInput { public static void main(String[] args) { File file = new File("C:\\MyFile.txt"); FileInputStream fis = null; BufferedInputStream bis = null; DataInputStream dis = null; try { fis = new FileInputStream(file); // Here BufferedInputStream is added for fast reading. bis = new BufferedInputStream(fis); dis = new DataInputStream(bis); // dis.available() returns 0 if the file does not have more lines. while (dis.available() != 0) { // this statement reads the line from the file and print it to // the console. System.out.println(dis.readLine()); } // dispose all the resources after using them. fis.close(); bis.close(); dis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 

पूरी धारा की चेनिंग चीज की उपेक्षा करना, यह विचार यह है

  1. संसाधन को प्रारंभ करें, जिसे साफ करने की आवश्यकता है
  2. संसाधन का उपयोग करें
  3. इसे साफ करने के लिए सुनिश्चित करें

इस तरह आप इसे रूबी में करते हैं

 File.open("readfile.rb", "r") do |infile| while (line = infile.gets) puts "#{counter}: #{line}" counter = counter + 1 end end 

बेतहाशा अलग। इसे एक तोड़कर नीचे

  1. फ़ाइल क्लास को बताएं कि संसाधन कैसे प्रारंभ करें
  2. फ़ाइल वर्ग को बताएं कि इसके साथ क्या करना है
  3. अभी भी टाइप कर रहे हैं जो जावा लोग हंसी 😉

यहां, एक और दो चरणों को संभालने के बजाय, आप मूल रूप से उस अन्य कक्षा में भाग लेते हैं। जैसा कि आप देख सकते हैं, यह नाटकीय रूप से आपके द्वारा लिखे गए कोड की मात्रा को नीचे लाता है, जिससे चीजें पढ़ने में आसान हो जाता है, और मेमोरी लीक जैसी चीजों की संभावना कम हो जाती है, या फ़ाइल लॉक को साफ नहीं हो रहा है

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

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

मैंने यह लेख बहुत उपयोगी होना पाया विशेष रूप से, निम्न उदाहरण:

 #!/usr/bin/ruby def test yield 5 puts "You are in the method test" yield 100 end test {|i| puts "You are in the block #{i}"} test do |i| puts "You are in the block #{i}" end 

जो निम्नलिखित आउटपुट देना चाहिए:

 You are in the block 5 You are in the method test You are in the block 100 You are in the block 5 You are in the method test You are in the block 100 

इसलिए अनिवार्य रूप से हर बार जब कॉल करने के लिए कॉल किया जाता yield रब्बी को कोड को ब्लॉक या अंदर {} चलाना होगा। यदि कोई पैरामीटर yield प्रदान किया जाता yield तो यह ब्लॉक को एक पैरामीटर के रूप में प्रदान किया जाएगा।

मेरे लिए, यह पहली बार था कि मैं वास्तव में क्या कर रहा था वास्तव में क्या do ब्लॉक कर रहे थे। यह मूल रूप से आंतरिक डेटा संरचनाओं तक पहुंच प्रदान करने के लिए फ़ंक्शन के लिए एक तरीका है, इसे पुनरावृत्ति या फ़ंक्शन के कॉन्फ़िगरेशन के लिए होना चाहिए।

तो जब रेल में आप निम्नलिखित लिखते हैं:

 respond_to do |format| format.html { render template: "my/view", layout: 'my_layout' } end 

यह respond_to फ़ंक्शन को चलाएगा जो कि (आंतरिक) format पैरामीटर के साथ ब्लॉक format है। फिर आप इस आंतरिक चर पर .html फ़ंक्शन कॉल करते हैं जो बदले में render कमांड को चलाने के लिए कोड ब्लॉक देता है। ध्यान दें कि। .html केवल तभी उपलब्ध होगा यदि यह फ़ाइल प्रारूप का अनुरोध किया गया है। (तकनीकी: ये कार्य वास्तव में block.call उपयोग नहीं yield जैसा कि आप स्रोत से देख सकते हैं लेकिन कार्यक्षमता अनिवार्य रूप से एक ही है, चर्चा के लिए यह प्रश्न देखें।) यह फ़ंक्शन कुछ प्रारंभिक क्रिया करने के लिए एक तरीका प्रदान करता है, तब से इनपुट लेते हैं कॉलिंग कोड और उसके बाद आवश्यक होने पर प्रसंस्करण जारी रखें।

या किसी अन्य तरीके से, यह एक समारोह के समान है, जो किसी अनाम कार्य को तर्क के रूप में लेता है और फिर इसे जावास्क्रिप्ट में बुलाता है

मैं कभी कभी इस तरह "उपज" का उपयोग करता हूं:

 def add_to_http "http://#{yield}" end puts add_to_http { "www.example.com" } puts add_to_http { "www.victim.com"} 

उपज, इसे आसानी से रखने के लिए, जिस विधि को आप बनाने और ब्लॉकों को कॉल करते हैं उसे अनुमति दें। उपज कीवर्ड विशेष रूप से उस स्थान पर होता है जहां ब्लॉक में 'सामान' किया जाएगा।

रुबी में, एक ब्लॉक मूल रूप से कोड का एक हिस्सा होता है जिसे किसी भी विधि से पारित किया और निष्पादित किया जा सकता है। ब्लॉक हमेशा विधियों के साथ उपयोग किए जाते हैं, जो आम तौर पर उनसे डेटा फ़ीड करते हैं (तर्क के रूप में)।

रूबी रत्नों (रेल सहित) में और अच्छी तरह से लिखा रूबी कोड में ब्लाकों का व्यापक रूप से उपयोग किया जाता है। वे ऑब्जेक्ट नहीं हैं, इसलिए चर को सौंपा नहीं जा सकता।

बेसिक सिंटैक्स

एक ब्लॉक {} या do..end द्वारा संलग्न कोड का एक टुकड़ा है। सम्मेलन के अनुसार, एकल-पंक्ति ब्लॉकों के लिए घुंघराले ब्रेस वाक्यविन्यास का उपयोग किया जाना चाहिए और do..end सिंटैक्स को बहु-लाइन ब्लॉकों के लिए उपयोग किया जाना चाहिए।

 { # This is a single line block } do # This is a multi-line block end 

किसी भी विधि को एक अन्तर्निहित तर्क के रूप में एक ब्लॉक प्राप्त हो सकता है। किसी विधि के भीतर उपज कथन द्वारा एक ब्लॉक निष्पादित किया जाता है। बुनियादी वाक्यविन्यास है:

 def meditate print "Today we will practice zazen" yield # This indicates the method is expecting a block end # We are passing a block as an argument to the meditate method meditate { print " for 40 minutes." } Output: Today we will practice zazen for 40 minutes. 

जब उपज विवरण प्राप्त हो जाता है, तो ध्यान पद्धति का उपयोग ब्लॉक पर नियंत्रण पैदा करता है, ब्लॉक के अंदर कोड को निष्पादित किया जाता है और विधि को वापस लौटा दिया जाता है, जो उपज बयान के तुरंत बाद निष्पादन को शुरू करता है।

जब एक पद्धति में एक उपज बयान होता है, तो वह कॉलिंग समय पर एक ब्लॉक प्राप्त करने की उम्मीद कर रहा है। यदि कोई ब्लॉक प्रदान नहीं किया गया है, तो उपज कथन तक पहुंचने के बाद एक अपवाद फेंका जाएगा। हम ब्लॉक वैकल्पिक बना सकते हैं और उठाए गए अपवाद से बच सकते हैं:

 def meditate puts "Today we will practice zazen." yield if block_given? end meditate Output: Today we will practice zazen. 

एक विधि में कई ब्लॉकों को पारित करना संभव नहीं है। प्रत्येक विधि केवल एक ब्लॉक प्राप्त कर सकते हैं

अधिक देखें: http://www.zenruby.info/2016/04/introduction-to-blocks-in-ruby.html

विधि में किसी मूल्य को वापस करने के लिए नमी ब्लॉक के रूप में यील्ड का उपयोग किया जा सकता है निम्नलिखित कोड पर विचार करें:

 Def Up(anarg) yield(anarg) end 

आप एक विधि "ऊपर" बना सकते हैं जो एक तर्क को सौंपा गया है। आप अब इस तर्क को उत्पन्न करने के लिए निर्दिष्ट कर सकते हैं जो एक संबद्ध ब्लॉक को कॉल और निष्पादित करेगा। आप पैरामीटर सूची के बाद ब्लॉक निर्दिष्ट कर सकते हैं।

 Up("Here is a string"){|x| x.reverse!; puts(x)} 

जब अप विधि एक तर्क के साथ उपज कॉल करता है, तो यह अनुरोध को संसाधित करने के लिए ब्लॉक वैरिएबल को पारित किया जाता है।