Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

रूबी में पैटर्न मिलान का परिचय

आइए रूबी में पैटर्न मिलान के बारे में एक संक्षिप्त चर्चा के साथ शुरू करें, यह क्या करता है, और यह कैसे कोड पठनीयता को बेहतर बनाने में मदद कर सकता है।

यदि आप कुछ साल पहले मेरे जैसे कुछ हैं, तो आप इसे रेगेक्स में पैटर्न मिलान के साथ भ्रमित कर सकते हैं। यहां तक ​​कि बिना किसी अन्य संदर्भ के 'पैटर्न मिलान' की एक त्वरित Google खोज भी आपको उस परिभाषा के काफी करीब सामग्री लाती है।

औपचारिक रूप से, पैटर्न मिलान किसी भी डेटा की जांच करने की प्रक्रिया है (चाहे वह वर्णों का एक क्रम हो, टोकन की एक श्रृंखला, एक टपल, या कुछ और) अन्य डेटा के विरुद्ध।

प्रोग्रामिंग के संदर्भ में, भाषा की क्षमताओं के आधार पर, इसका मतलब निम्न में से कोई भी हो सकता है:

  1. अपेक्षित डेटा प्रकार से मिलान करना
  2. अपेक्षित हैश संरचना (जैसे विशिष्ट कुंजियों की उपस्थिति) के विरुद्ध मिलान करना
  3. अपेक्षित सरणी लंबाई के विरुद्ध मिलान
  4. मिलानों (या उनमें से एक भाग) को कुछ चरों पर असाइन करना

पैटर्न मिलान में मेरा पहला प्रयास अमृत के माध्यम से हुआ था। पैटर्न मिलान के लिए अमृत के पास प्रथम श्रेणी का समर्थन है, इतना अधिक कि = ऑपरेटर, वास्तव में, मिलान . है साधारण असाइनमेंट के बजाय ऑपरेटर।

इसका मतलब है कि अमृत में, निम्नलिखित वास्तव में मान्य कोड है:

iex> x =1iex> 1 =x 

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

रूबी पैटर्न केस से मेल खाता है /में

रूबी एक विशेष केस . के साथ मिलान पैटर्न का समर्थन करती है /में अभिव्यक्ति। वाक्य रचना है:

केस <अभिव्यक्ति> # ...में  # ...else # ...end 

इसे केस . के साथ भ्रमित नहीं होना चाहिए /कब अभिव्यक्ति। कब और में शाखाओं को एक केस में नहीं मिलाया जा सकता ।

यदि आप कोई अन्य प्रदान नहीं करते हैं अभिव्यक्ति, कोई भी असफल मिलान एक NoMatchingPatternError उत्पन्न करेगा ।

रूबी में पैटर्न मिलान सरणी

पैटर्न मिलान का उपयोग डेटा प्रकारों, लंबाई या मानों के विरुद्ध पूर्व-आवश्यक संरचनाओं के लिए सरणियों से मिलान करने के लिए किया जा सकता है।

उदाहरण के लिए, निम्नलिखित सभी मैच हैं (ध्यान दें कि केवल पहला इन मामले . के रूप में मूल्यांकन किया जाएगा पहला मैच देखना बंद कर देता है):

case [1, 2, "Three"]in [Integer, Integer, String] "matches"in [1, 2, "Three"] "matches" in [Integer, *] "matches" # क्योंकि * एक स्प्रेड ऑपरेटर है जो [a, *] "मिलान" # में किसी भी चीज़ से मेल खाता है और वेरिएबल a का मान अब 1end है 

जब आप किसी मेथड कॉल से कई सिग्नल उत्पन्न करना चाहते हैं तो इस प्रकार का पैटर्न मिलान क्लॉज बहुत उपयोगी होता है।

इलीक्सिर की दुनिया में, इसका उपयोग अक्सर ऑपरेशन करते समय किया जाता है जिसमें :ok . दोनों हो सकते हैं परिणाम और एक :त्रुटि परिणाम, उदाहरण के लिए, डेटाबेस में डाला गया।

यहां बताया गया है कि हम इसे बेहतर पठनीयता के लिए कैसे उपयोग कर सकते हैं:

def create case save(model_params) in [:ok, model] render :json => model in [:error,errors] render :json => error endend # आपके कोड में कहीं, उदा। एक वैश्विक सहायक या आपके मॉडल बेस क्लास के अंदर (एक अलग नाम के साथ)। def save(attrs) model =Model.new(attrs) model.save ? [:ठीक है, मॉडल] :[:त्रुटि, मॉडल.त्रुटियां]अंत 

रूबी में वस्तुओं का मिलान करने वाला पैटर्न

आप एक विशिष्ट संरचना को लागू करने के लिए रूबी में वस्तुओं का मिलान भी कर सकते हैं:

केस {a:1, b:2}in {a:Integer} "matches" # डिफ़ॉल्ट रूप से, सभी ऑब्जेक्ट मैच आंशिक {a:Integer, **} "matches" # होते हैं और एक जैसे होते हैं {a:Integer}in {a:a} "matches" # और वेरिएबल a का मान अब 1in {a:Integer => a} "matches" # है और वेरिएबल a का मान अब 1in {a:1 है। b:b} "मिलान" # और वेरिएबल b का मान अब 2in {a:Integer, **nil} "मेल नहीं खाता" # यह तभी मेल खाएगा जब ऑब्जेक्ट में a हो और कोई अन्य keyend न हो 

किसी भी पैरा के खिलाफ मिलान के लिए मजबूत नियम लागू करते समय यह बहुत अच्छा काम करता है।

उदाहरण के लिए, यदि आप एक फैंसी अभिवादन लिख रहे हैं, तो इसकी निम्नलिखित (दृढ़ राय वाली) संरचना हो सकती है:

में {अभिवादन:अभिवादन, नाम:नाम} {नाम:नाम} में "#{ग्रीटिंग}, #{नाम}" डालता है (अभिवादन:"हैलो", नाम:नाम) {अभिवादन:अभिवादन} में अभिवादन (अभिवादन:अभिवादन) , नाम:"बेनामी") अन्य अभिवादन (अभिवादन:"हैलो", नाम:"बेनामी") अंत में अभिवादन # हैलो, बेनामीग्रीट (नाम:"जॉन") # हैलो, जॉनग्रीट (प्रथम_नाम:"जॉन", अंतिम_नाम:"डो ") # हैलो, जॉन डोग्रीट (अभिवादन:"बोनजोर", प्रथम_नाम:"जॉन", अंतिम_नाम:"डो") # बोनजोर, जॉन डोग्रीट (अभिवादन:"बोनजोर") # बोनजोर, बेनामी

रूबी में वैरिएबल बाइंडिंग और पिनिंग

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

  1. मजबूत प्रकार के मिलान के साथ, उदा. इन [पूर्णांक => a] या में {a:Integer => a}
  2. प्रकार विनिर्देश के बिना, उदा. इन [a, 1, 2] या में {a:a}
  3. चर नाम के बिना, जो डिफ़ॉल्ट रूप से कुंजी नाम का उपयोग करता है, उदा. में {a:} a . नामक एक वेरिएबल को परिभाषित करेगा कुंजी a . पर मान के साथ ।
  4. बाँध आराम, उदा. इन [पूर्णांक, *बाकी] या में {a:Integer, **rest}

तब, जब हम उप-पैटर्न के रूप में मौजूदा चर का उपयोग करना चाहते हैं, तो हम कैसे मेल खा सकते हैं? यह तब होता है जब हम चर पिनिंग . का उपयोग कर सकते हैं ^ . के साथ (पिन) ऑपरेटर:

a =1केस {a:1, b:2}में {a:^a} "मैच"अंत 

आप इसका उपयोग तब भी कर सकते हैं जब एक चर को एक पैटर्न में ही परिभाषित किया जाता है, जिससे आप इस तरह के शक्तिशाली पैटर्न लिख सकते हैं:

केस ऑर्डर में {बिलिंग_एड्रेस:​​{सिटी:}, शिपिंग_एड्रेस:​​{सिटी:^सिटी}} "बिलिंग और शिपिंग दोनों एक ही शहर में हैं" और बढ़ाएं "बिलिंग और शिपिंग दोनों एक ही शहर में होने चाहिए "अंत 

वैरिएबल बाइंडिंग के साथ उल्लेख करने के लिए एक महत्वपूर्ण विचित्रता यह है कि भले ही पैटर्न पूरी तरह से मेल नहीं खाता हो, फिर भी वेरिएबल बाध्य रहेगा। यह कभी-कभी उपयोगी हो सकता है।

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

शहर ="एम्स्टर्डम"आदेश ={बिलिंग_पता:{शहर:"बर्लिन"}, शिपिंग_पता:{शहर:"ज़्यूरिख"}}मामला आदेश {बिलिंग_पता:{शहर:}, शिपिंग_पता:{शहर:^ शहर}} डालता है "बिलिंग और शिपिंग दोनों एक ही शहर के लिए हैं" और कहते हैं "बिलिंग और शिपिंग दोनों एक ही शहर में होने चाहिए" एंडपुट्स शहर # एम्स्टर्डम के बजाय बर्लिन 

रूबी की कस्टम क्लास से मेल खाना

रूबी में कस्टम क्लास पैटर्न मिलान को जागरूक करने के लिए आप कुछ विशेष तरीकों को लागू कर सकते हैं।

उदाहरण के लिए, किसी उपयोगकर्ता को उसके first_name . से मिलान करने के लिए पैटर्न और last_name , हम परिभाषित कर सकते हैं deconstruct_keys कक्षा में:

वर्ग उपयोगकर्ता def deconstruct_keys(keys) {first_name:first_name, last_name:last_name} एंडेंड केस यूजरिन {first_name:"John"} "Hey, John" end डालता है। 

कुंजी deconstruct_keys . के लिए तर्क इसमें वे कुंजियाँ होती हैं जिनका पैटर्न में अनुरोध किया गया है। यह रिसीवर के लिए केवल आवश्यक कुंजियाँ प्रदान करने का एक तरीका है यदि उन सभी की गणना करना महंगा है।

उसी तरह जैसे deconstruct_keys , हम deconstruct . का कार्यान्वयन प्रदान कर सकते हैं वस्तुओं को एक सरणी के रूप में पैटर्न मिलान करने की अनुमति देने के लिए। उदाहरण के लिए, मान लें कि हमारे पास स्थान है वह वर्ग जिसमें अक्षांश और देशांतर हो। deconstruct_keys using का उपयोग करने के अलावा अक्षांश और देशांतर कुंजियाँ प्रदान करने के लिए, हम [अक्षांश, देशांतर] के रूप में एक सरणी दिखा सकते हैं साथ ही:

क्लास लोकेशन डिकॉन्स्ट्रक्ट [अक्षांश, देशांतर] एंडएंड केस लोकेशन में [फ्लोट => अक्षांश, फ्लोट => देशांतर] "#{अक्षांश}, #{देशांतर}"अंत डालता है 

जटिल पैटर्न के लिए गार्ड का उपयोग करना

यदि हमारे पास जटिल पैटर्न हैं जिन्हें नियमित पैटर्न मिलान ऑपरेटरों के साथ प्रदर्शित नहीं किया जा सकता है, तो हम if . का भी उपयोग कर सकते हैं (या जब तक ) मैच के लिए एक गार्ड प्रदान करने के लिए बयान:

केस [1, 2] में [a, b] अगर b ==a * 2 "मैच" और "नो मैच" खत्म होता है 

पैटर्न मिलान => . के साथ /में केस के बिना

यदि आप रूबी 3+ पर हैं, तो आपके पास जादू से मेल खाने वाले और भी अधिक पैटर्न तक पहुंच है। रूबी 3 से शुरू होकर, पैटर्न मिलान बिना किसी केस स्टेटमेंट के सिंगल लाइन में किया जा सकता है:

  [1, 2, "तीन"] => [पूर्णांक => एक, दो, स्ट्रिंग => तीन] एक डालता है # 1पुट दो # 2पुट तीन # तीन # ऊपर के समान [1, 2, " तीन"] में [पूर्णांक => एक, दो, स्ट्रिंग => तीन] 

यह देखते हुए कि उपरोक्त सिंटैक्स में else नहीं है क्लॉज, यह सबसे उपयोगी तब होता है जब डेटा संरचना पहले से जानी जाती है।

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

  क्लास एडमिनकंट्रोलर <ऑथेंटिकेटेड कंट्रोलर से पहले_एक्शन:वेरिफाई_एडमिन प्राइवेट डीईएफ़ वेरिफाई_एडमिन करंट। 

रूबी में पैटर्न मिलान:इस स्पेस को देखें

सबसे पहले, पैटर्न मिलान को समझने में थोड़ा अजीब लग सकता है। कुछ के लिए, यह महिमामंडित वस्तु/सरणी विघटन जैसा लग सकता है।

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

यदि आप रूबी 2.7 पर हैं, तो पैटर्न मिलान (केस . के साथ) /में ) अभी भी प्रायोगिक है। रूबी 3 के साथ, केस /में नए पेश किए गए सिंगल-लाइन पैटर्न मिलान एक्सप्रेशन प्रयोगात्मक हैं, जबकि स्थिर में स्थानांतरित हो गया है। चेतावनियों को Warning[:experimental] =false के साथ बंद किया जा सकता है कोड में या -W:no-प्रयोगात्मक . में कमांड-लाइन कुंजी।

हालांकि रूबी में पैटर्न मिलान अभी भी अपने प्रारंभिक चरण में है, मुझे आशा है कि आपको यह परिचय उपयोगी लगा होगा और आप भी उतने ही उत्साहित होंगे जितना कि मैं आने वाले भविष्य के विकास को लेकर!

पी.एस. यदि आप रूबी मैजिक पोस्ट को प्रेस से बाहर होते ही पढ़ना चाहते हैं, तो हमारे रूबी मैजिक न्यूज़लेटर की सदस्यता लें और कभी भी एक भी पोस्ट मिस न करें!


  1. रूबी में तंत्रिका नेटवर्क:एक डरावना परिचय

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

  1. रूबी में 9 नई सुविधाएँ 2.6

    रूबी का एक नया संस्करण नई सुविधाओं और प्रदर्शन में सुधार के साथ आ रहा है। क्या आप परिवर्तनों के साथ बने रहना चाहेंगे? आइए एक नज़र डालते हैं! अंतहीन रेंज रूबी 2.5 और पुराने संस्करण पहले से ही अंतहीन श्रेणी के एक रूप का समर्थन करते हैं (Float::INFINITY के साथ) ), लेकिन रूबी 2.6 इसे अगले स्तर पर ले

  1. रूबी में डेकोरेटर डिजाइन पैटर्न

    डेकोरेटर डिजाइन पैटर्न क्या है? और आप अपने रूबी प्रोजेक्ट्स में इस पैटर्न का उपयोग कैसे कर सकते हैं? डेकोरेटर डिज़ाइन पैटर्न नई क्षमताओं . जोड़कर किसी ऑब्जेक्ट को बेहतर बनाने में आपकी सहायता करता है इसमें बिना कक्षा बदले। आइए एक उदाहरण देखें! लॉगिंग और प्रदर्शन इस उदाहरण में हम रेस्ट-क्लाइंट जैस