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

रेल उन्मुख प्रोग्रामिंग रेल में ड्राई-मोनाड्स का उपयोग करना

त्रुटि प्रबंधन हर कार्यक्रम का एक महत्वपूर्ण हिस्सा है। कोड के एक टुकड़े के कार्यान्वयन के दौरान कौन सी त्रुटियां उत्पन्न हो सकती हैं, इसके बारे में सक्रिय होना महत्वपूर्ण है। इन त्रुटियों को इस तरह से नियंत्रित किया जाना चाहिए जो सुनिश्चित करता है कि आउटपुट का उत्पादन होता है जो प्रत्येक त्रुटि और आवेदन के चरण का ठीक से वर्णन करता है। फिर भी, इसे इस तरह हासिल करना भी महत्वपूर्ण है जिससे यह सुनिश्चित हो सके कि आपका कोड कार्यात्मक और पठनीय बना रहे। आइए एक ऐसे प्रश्न का उत्तर देकर शुरू करें जो आपके पास पहले से हो:रेलवे ओरिएंटेड प्रोग्रामिंग क्या है?

रेलवे ओरिएंटेड प्रोग्रामिंग

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

validate user -> update address -> send mail upon successful update

इनमें से प्रत्येक चरण या तो विफल हो सकता है या सफल हो सकता है, और किसी भी चरण की विफलता पूरी प्रक्रिया की विफलता की ओर ले जाती है, क्योंकि फ़ंक्शन का उद्देश्य प्राप्त नहीं होता है।

रेलवे ओरिएंटेड प्रोग्रामिंग (आरओपी) स्कॉट व्लास्चिन . द्वारा आविष्कार किया गया एक शब्द है जो इस तरह के कार्यों में त्रुटि प्रबंधन के लिए रेलवे स्विच सादृश्य को लागू करता है। रेलवे स्विच (यूके में "पॉइंट्स" कहा जाता है) ट्रेनों को एक ट्रैक से दूसरे ट्रैक पर गाइड करता है। स्कॉट इस सादृश्य को इस अर्थ में नियोजित करता है कि प्रत्येक चरण की सफलता/विफलता आउटपुट रेलवे स्विच की तरह कार्य करता है, क्योंकि यह आपको एक सफलता ट्रैक या एक विफलता ट्रैक पर ले जा सकता है।

रेल उन्मुख प्रोग्रामिंग रेल में ड्राई-मोनाड्स का उपयोग करना रेलवे स्विच के रूप में कार्य करने वाले सफलता/विफलता आउटपुट

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

रेल उन्मुख प्रोग्रामिंग रेल में ड्राई-मोनाड्स का उपयोग करना एक साथ जंजीर में बंधे कई चरणों की सफलता/विफलता आउटपुट

यह दो-ट्रैक सादृश्य रेलवे उन्मुख प्रोग्रामिंग के पीछे का विचार है। यह सुनिश्चित करने के लिए कि एक चरण में विफलता पूरी प्रक्रिया की विफलता है, यह सुनिश्चित करने के लिए इन सफलता/विफलता आउटपुट को हर चरण (यानी, प्रत्येक विधि जो एक प्रक्रिया का हिस्सा है) पर वापस करने का प्रयास करता है। प्रत्येक चरण के सफल समापन से ही समग्र सफलता प्राप्त होती है।

दैनिक जीवन का एक उदाहरण

कल्पना करें कि आपका लक्ष्य द मिल्क शेकर्स नामक स्टोर से व्यक्तिगत रूप से दूध का कार्टन खरीदना है . इसमें शामिल संभावित कदम इस प्रकार होंगे:

Leave your house -> Arrive at The Milk Shakers -> Pick up a carton of milk -> Pay for the carton of milk

यदि आप अपने घर से बाहर नहीं निकल सकते हैं, तो पूरी प्रक्रिया विफल है क्योंकि पहला कदम विफलता है। क्या होगा अगर आप घर से निकलकर वॉलमार्ट में चले गए? प्रक्रिया अभी भी विफल है क्योंकि आप निर्दिष्ट स्टोर पर नहीं गए थे। तथ्य यह है कि आप वॉलमार्ट से दूध प्राप्त कर सकते हैं इसका मतलब यह नहीं है कि प्रक्रिया जारी रहेगी। आरओपी वॉलमार्ट में प्रक्रिया को रोकता है और एक विफलता आउटपुट देता है जिससे आपको पता चलता है कि प्रक्रिया विफल हो गई क्योंकि स्टोर मिल्क शेकर्स नहीं था। हालाँकि, यदि आप सही स्टोर पर गए होते, तो प्रक्रिया जारी रहती, आउटपुट की जाँच करना और या तो प्रक्रिया को समाप्त करना या अगले चरण पर आगे बढ़ना। यह अधिक पठनीय और सुरुचिपूर्ण त्रुटि प्रबंधन सुनिश्चित करता है और इसे if/else . के बिना कुशलतापूर्वक प्राप्त करता है और return अलग-अलग चरणों को जोड़ने वाले बयान।

रेल में, हम ड्राई मोनाड्स नामक रत्न का उपयोग करके इस दो-ट्रैक रेलवे आउटपुट को प्राप्त कर सकते हैं। ।

शुष्क मोनाड का परिचय और वे कैसे काम करते हैं

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

जैसा कि इसके दस्तावेज़ीकरण में कहा गया है, जिसकी मैं आपको समीक्षा करने की सलाह देता हूं, सूखी मोनैड रूबी के लिए सामान्य मोनैड का एक सेट है। मोनाड त्रुटियों, अपवादों और श्रृंखलन कार्यों को संभालने का एक शानदार तरीका प्रदान करते हैं ताकि कोड बहुत अधिक समझ में आ सके और सभी ifs and elses के बिना सभी वांछित त्रुटि प्रबंधन हो। . हम परिणाम मोनाड . पर ध्यान केंद्रित करेंगे जैसा कि हमें अपनी सफलता/असफलता के परिणाम प्राप्त करने के लिए ठीक यही चाहिए, जिसके बारे में हमने पहले बात की थी।

आइए निम्नलिखित कमांड का उपयोग करके रेलवे-ऐप नामक एक नया रेल ऐप शुरू करें:

rails new railway-app -T

कमांड में -T का अर्थ है कि हम परीक्षण फ़ोल्डर को छोड़ देंगे क्योंकि हम परीक्षण के लिए RSpec का उपयोग करना चाहते हैं।

इसके बाद, हम अपने Gemfile में आवश्यक रत्न जोड़ते हैं:gem dry-monads सफलता/विफलता परिणामों के लिए और gem rspec-rails परीक्षण और विकास समूह में हमारे परीक्षण ढांचे के रूप में। अब, हम bundle install चला सकते हैं हमारे ऐप में जोड़े गए रत्नों को स्थापित करने के लिए। हमारी परीक्षण फ़ाइलें और सहायक उत्पन्न करने के लिए, हालांकि, हमें निम्न आदेश चलाने की आवश्यकता है:

rails generate rspec:install

एक फ़ंक्शन को कई चरणों में विभाजित करें

अपने कार्य को छोटे-छोटे तरीकों में विभाजित करने की सलाह दी जाती है जो आपके अंतिम लक्ष्य को प्राप्त करने के लिए मिलकर काम करते हैं। इन विधियों से त्रुटियाँ, यदि कोई हों, हमें यह पहचानने में मदद करती हैं कि हमारी प्रक्रिया कहाँ विफल हुई और हमारे कोड को साफ और पठनीय बनाए। यदि मांगे गए मॉडल और रंग उपलब्ध हैं, यदि निर्माण का वर्ष वर्ष 2000 से पहले नहीं है, और यदि शहर को वितरित किया जाना है, तो वह पास के शहरों की सूची में है। यह दिलचस्प होना चाहिए। :)

आइए वितरण प्रक्रिया को कई चरणों में विभाजित करके शुरू करें:

  • सत्यापित करें कि निर्माण का वर्ष वर्ष 2000 से पहले का नहीं है।
  • सत्यापित करें कि मॉडल उपलब्ध है।
  • सत्यापित करें कि रंग उपलब्ध है।
  • सत्यापित करें कि जिस शहर को डिलीवर किया जाना है वह पास का शहर है।
  • एक संदेश भेजें कि कार डिलीवर हो जाएगी।

अब जबकि हमारे पास अलग-अलग चरण तय हो गए हैं, आइए कोड में गोता लगाएँ।

इनपुट सफलता/विफलता आउटपुट परिणाम

हमारे ऐप/मॉडल फोल्डर में, car_dealership.rb नाम की एक फाइल बनाते हैं। और इस कक्षा को महत्वपूर्ण विवरण के साथ प्रारंभ करें। फ़ाइल के शीर्ष पर, हमें dry/monads require की आवश्यकता है , और कक्षा के नाम के ठीक बाद, हमें DryMonads[:result, :do] शामिल करना होगा . यह परिणाम मोनाड और डू नोटेशन (जो उपज शब्द का उपयोग करके कई मोनैडिक संचालन के संयोजन को संभव बनाता है) हमारे लिए उपलब्ध कराता है।

require 'dry/monads'

class CarDealership

include Dry::Monads[:result, :do]

  def initialize
    @available_models = %w[Avalon Camry Corolla Venza]
    @available_colors = %w[red black blue white]
    @nearby_cities = %w[Austin Chicago Seattle]
  end
end

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

def deliver_car(year,model,color,city)
  yield check_year(year)
  yield check_model(model)
  yield check_city(city)
  yield check_color(color)

  Success("A #{color} #{year} Toyota #{model} will be delivered to #{city}")
end

अब, अन्य सभी विधियों को जोड़ते हैं और उनकी जाँच के परिणामों के आधार पर उन्हें सफलता/विफलता परिणाम देते हैं।

def check_year(year)
  year < 2000 ? Failure("We have no cars manufactured in year #{year}") : Success('Cars of this year are available')
end

def check_model(model)
  @available_models.include?(model) ? Success('Model available') : Failure('The model requested is unavailable')
end
def check_color(color)
  @available_colors.include?(color) ? Success('This color is available') : Failure("Color #{color} is unavailable")
end

def check_city(city)
  @nearby_cities.include?(city) ? Success("Car deliverable to #{city}") : Failure('Apologies, we cannot deliver to this city')
end

वर्तमान में हमारे पास हमारी कक्षा और हमें आवश्यक सभी विधियां हैं। यह कैसे चलेगा? आइए इस वर्ग का एक नया उदाहरण बनाकर और deliver_car . पर कॉल करके पता करें विभिन्न तर्कों के साथ विधि।

good_dealer = CarDealership.new

good_dealer.deliver_car(1990, 'Venza', 'red', 'Austin')
#Failure("We have no cars manufactured in year 1990")

good_dealer.deliver_car(2005, 'Rav4', 'red', 'Austin')
#Failure("The model requested is unavailable")

good_dealer.deliver_car(2005, 'Venza', 'yellow', 'Austin')
#Failure("Color yellow is unavailable")

good_dealer.deliver_car(2000, 'Venza', 'red', 'Surrey')
#Failure("Apologies, we cannot deliver to this city")

good_dealer.deliver_car(2000, 'Avalon', 'blue', 'Austin')
#Success("A blue 2000 Toyota Avalon will be delivered to Austin")

जैसा कि ऊपर दिखाया गया है, डिलीवर_कार विधि का विफलता परिणाम उस विधि के आधार पर भिन्न होता है जिस पर यह विफल होता है। उस पद्धति की विफलता उसकी विफलता बन जाती है, और सभी विधियों की सफलता पर, यह अपना स्वयं का सफलता परिणाम देता है। साथ ही, यह न भूलें कि ये चरण अलग-अलग तरीके हैं जिन्हें deliver_car से स्वतंत्र रूप से भी कहा जा सकता है तरीका। एक उदाहरण नीचे दिखाया गया है:

good_dealer.check_color('wine')
#Failure("Color wine is unavailable")

good_dealer.check_model('Camry')
#Success('Model available')

RSpec के साथ परीक्षण

उपरोक्त कोड का परीक्षण करने के लिए, हम अपने विशिष्ट फ़ोल्डर में जाते हैं और एक फ़ाइल बनाते हैं car_dealership_spec.rb पथ में spec/models . पहली पंक्ति में, हमें हमारे 'rails_helper' की आवश्यकता है। हम पहले असफलता और फिर सफलता के संदर्भ में परीक्षण लिखेंगे।

require 'rails_helper'

describe CarDealership do
  describe "#deliver_car" don
    let(:toyota_dealer) { CarDealership.new }
    context "failure" do
      it "does not deliver a car with the year less than 2000" do
        delivery = toyota_dealer.deliver_car(1990, 'Venza', 'red', 'Austin')
        expect(delivery.success).to eq nil
        expect(delivery.failure).to eq 'We have no cars manufactured in  year 1990'
      end

       it "does not deliver a car with the year less than 2000" do
        delivery = toyota_dealer.deliver_car(2005, 'Venza', 'yellow', 'Austin')
        expect(delivery.success).to eq nil
        expect(delivery.failure).to eq 'Color yellow is unavailable'
      end
   end
 end
end

जैसा कि ऊपर दिखाया गया है, हम result.failure . का उपयोग करके विफलता या सफलता के परिणामों तक पहुंच सकते हैं या result.success . सफलता के संदर्भ में, परीक्षण कुछ इस तरह दिखाई देंगे:

context "success" do
  it "delivers a car when all conditions are met" do
    delivery = toyota_dealer.deliver_car(2000, 'Avalon', 'blue', 'Austin')
    expect(delivery.success).to eq 'A blue 2000 Toyota Avalon will be delivered to Austin'
    expect(delivery.failure).to eq nil
  end
end

अब, आप आपूर्ति किए गए तर्कों को deliver_car में ट्वीक करके विफलता के संदर्भ में अन्य परीक्षण जोड़ सकते हैं तरीका। आप उन स्थितियों के लिए अपने कोड में अन्य चेक भी जोड़ सकते हैं जहां एक अमान्य तर्क प्रदान किया गया है (उदाहरण के लिए, एक स्ट्रिंग वर्ष चर के लिए मान के रूप में प्रदान की जाती है और अन्य इसे पसंद करते हैं)। चल रहा है bundle exec rspec आपके टर्मिनल में परीक्षण चलाता है और दिखाता है कि सभी परीक्षण पास हो जाते हैं। आपको मूल रूप से एक ही समय में विफलता और सफलता के परिणामों के लिए अपने परीक्षण में चेक जोड़ने की आवश्यकता नहीं है, क्योंकि हमारे पास एक विधि के आउटपुट के रूप में दोनों नहीं हो सकते हैं। मैंने इसे केवल यह समझने में सहायता के लिए जोड़ा है कि जब हमारे पास एक विफलता परिणाम होता है और इसके विपरीत सफलता परिणाम कैसा दिखता है।

निष्कर्ष

यह केवल ड्राई-मोनाड्स का परिचय है और रेलवे उन्मुख प्रोग्रामिंग को प्राप्त करने के लिए इसे आपके ऐप में कैसे उपयोग किया जा सकता है। इसकी एक बुनियादी समझ को और अधिक जटिल संचालन और लेनदेन पर लागू किया जा सकता है। जैसा कि हमने देखा है, एक साफ और अधिक पठनीय कोड न केवल आरओपी का उपयोग करके प्राप्त किया जा सकता है, बल्कि त्रुटि प्रबंधन विस्तृत और कम तनावपूर्ण है। हमेशा याद रखें कि विफलता/सफलता के संक्षिप्त संदेशों को आपकी प्रक्रिया बनाने वाली विभिन्न विधियों में संलग्न करें, क्योंकि यह दृष्टिकोण यह पहचानने में सहायता करता है कि त्रुटि कहाँ और क्यों हुई। यदि आप ROP के बारे में अधिक जानकारी प्राप्त करना चाहते हैं, तो हम आपको Scott Wlaschin की इस प्रस्तुति को देखने की सलाह देते हैं।


  1. रेल के साथ हॉटवायर का उपयोग करना

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

  1. रेल के साथ टेलविंड सीएसएस का उपयोग करना

    CSS जादुई है लेकिन समय लेने वाली है। सुंदर, कार्यात्मक और सुलभ साइटों का उपयोग करना एक खुशी है, लेकिन अपना स्वयं का सीएसएस लिखना थकाऊ है। बूटस्ट्रैप जैसी कई CSS लाइब्रेरी में हाल के वर्षों में विस्फोट हुआ है और 2021 में Tailwind इस पैक में सबसे आगे है। हालांकि रेल टेलविंड आउट ऑफ बॉक्स के साथ नहीं आ

  1. रेल के साथ कोणीय का उपयोग करना 5

    आपने पहले कहानी सुनी है। आपके पास पहले से ही आपके विकेन्द्रीकृत और पूरी तरह से काम कर रहे बैक-एंड एपीआई और किसी भी सामान्य टूलसेट से बने फ्रंट-एंड पर चलने वाला एक एप्लिकेशन है। अब, आप कोणीय पर आगे बढ़ना चाहते हैं। या, शायद आप अपनी रेल परियोजनाओं के साथ एंगुलर को एकीकृत करने का एक तरीका ढूंढ रहे हैं