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

रूबी मेटाप्रोग्रामिंग इन एक्शन: रेल्स, सिनात्रा और पेपरक्लिप से वास्तविक-विश्व उदाहरण

आपने पहले रूबी मेटाप्रोग्रामिंग के बारे में पढ़ा होगा।

लेकिन…

यह थोड़ा भ्रमित करने वाला हो सकता है अगर आपके पास कुछ विशिष्ट उदाहरण न हों।

इसलिए इस लेख में:

हम कुछ लोकप्रिय ओपन-सोर्स प्रोजेक्ट्स को देखने जा रहे हैं जो रूबी मेटाप्रोग्रामिंग का उपयोग करते हैं।

जैसे प्रोजेक्ट्स:

  • रेल्स
  • सिनात्रा
  • पेपरक्लिप जेम

उन सभी में मेटाप्रोग्रामिंग के किसी न किसी रूप का उपयोग होता है।

चलिए कोड पर चलते हैं और पता लगाते हैं कि वे वास्तव में क्या कर रहे हैं!

रेल्स उदाहरण

रेल्स मेटाप्रोग्रामिंग का भारी उपयोग करता है, इसलिए यह शुरू करने के लिए एक अच्छी जगह है।

उदाहरण के लिए:

जब आप अपने रेल्स ऐप में वर्तमान वातावरण की जांच करना चाहते हैं, तो आप निम्न जैसा कुछ करते हैं।

 Rails.env.production? 

लेकिन env क्या है? और यह कैसे काम करता है?

जवाब StringInquirer क्लास में हैं, जो String का एक उपवर्ग है। यह क्लास method_missing का उपयोग करती है ताकि आप env.production? को env == production के बजाय कॉल कर सकें।

कोड ऐसा दिखता है:

 def method_missing(method_name, *arguments)
  if method_name[-1] == '?'
    self == method_name[0..-2]
  else
    super
  end
end 

यह कह रहा है:

“यदि मेथड नाम प्रश्न चिह्न से समाप्त होता है तो तुलना करें, अन्यथा पूर्वज श्रृंखला में ऊपर जाना जारी रखें”।

मूल कोड यहां पाया जा सकता है।

सिनात्रा डेलीगेशन

यदि आपने पहले सिनात्रा का उपयोग किया है तो आप जानते होंगे कि अपने रूट्स को परिभाषित करने के दो तरीके हैं:

  • get / post मेथड्स का सीधे उपयोग करके, किसी भी क्लास के बाहर।
  • Sinatra::Application से विरासत में मिली एक क्लास को परिभाषित करके।

सिनात्रा DSL (डोमेन-स्पेसिफिक लैंग्वेज) मेथड्स Sinatra::Application के अंदर परिभाषित हैं, तो आप उन्हें इस क्लास के बाहर कैसे उपयोग कर सकते हैं?

खैर, यहां दो चीजें हो रही हैं:

  • मेटाप्रोग्रामिंग
  • मॉड्यूल एक्सटेंशन

सिनात्रा base.rb के अंदर एक Sinatra::Delegator मॉड्यूल परिभाषित करता है, जिसका उपयोग मेथड कॉल्स को एक target पर डेलीगेट करने के लिए किया जाता है।

डिफ़ॉल्ट रूप से टारगेट Sinatra::Application पर सेट है।

यह delegate क्लास मेथड का एक सरलीकृत संस्करण है, जिसे Sinatra::Delegator में परिभाषित किया गया है:

 def self.delegate(*methods)
  methods.each do |method_name|
    define_method(method_name) do |*args, &block|
      Delegator.target.send(method_name, *args, &block)
    end
  end
end
delegate :get, :patch, :put, :post, :delete 

यह कोड मेथड्स का एक सेट बना रहा है (define_method के साथ) जो मेथड कॉल्स को Sinatra::Application ( Delegator.target के लिए डिफ़ॉल्ट मान) पर फॉरवर्ड करेगा।

फिर main ऑब्जेक्ट को Sinatra::Delegator में परिभाषित मेथड्स के साथ एक्सटेंड किया जाता है, जो सिनात्रा DSL को Sinatra::Application क्लास के बाहर उपलब्ध कराता है।

यह ध्यान देने योग्य है कि रूबी में मेथड डेलीगेशन के लिए दो बिल्ट-इन क्लासेस हैं, यदि आपको उनकी आवश्यकता हो: Delegator और Forwardable।

पेपरक्लिप जेम

पेपरक्लिप एक जेम है जो आपके एप्लिकेशन को फाइल अपलोड को संभालने की अनुमति देता है। फाइलें ActiveRecord मॉडल्स से जुड़ी होती हैं।

आप has_attached_file मेथड का उपयोग करके एक मॉडल पर एक अटैच्ड फाइल को परिभाषित कर सकते हैं।

इस तरह:

 class User
  has_attached_file :avatar, :styles => { :normal => "100x100#" }
end 

यह मेथड paperclip.rb पर परिभाषित है और यह मॉडल पर एक मेथड को परिभाषित करने के लिए मेटाप्रोग्रामिंग का उपयोग करता है।

इस मेथड का उपयोग फाइल अटैचमेंट (जो Paperclip::Attachment क्लास का एक इंस्टेंस है) तक पहुंचने के लिए किया जा सकता है।

उदाहरण के लिए, यदि अटैच्ड फाइल :avatar है, तो Paperclip मॉडल पर एक avatar मेथड को परिभाषित करेगा।

यहां define_instance_getter मेथड है, जो इसके लिए जिम्मेदार है:

 # @name => अटैचमेंट का नाम
# @klass => वह ActiveRecord मॉडल जहां यह मेथड परिभाषित किया जा रहा है
def define_instance_getter
  name = @name
  options = @options
  @klass.send :define_method, @name do |*args|
    ivar = "@attachment_#{name}"
    attachment = instance_variable_get(ivar)
    if attachment.nil?
      attachment = Attachment.new(name, self, options)
      instance_variable_set(ivar, attachment)
    end
    attachment
  end
end 

इस कोड से हम देख सकते हैं कि अटैचमेंट ऑब्जेक्ट @attachment_#{name} इंस्टेंस वेरिएबल के तहत संग्रहीत है।

हमारे उदाहरण में वह @attachment_avatar होगा।

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

यहां मूल स्रोत कोड है।

निष्कर्ष

जैसा कि आपने देखा, मेटाप्रोग्रामिंग एक बहुत शक्तिशाली और लचीली तकनीक है, लेकिन जब भी आप इसके लिए पहुंचना चाहें तो उस उद्धरण को याद रखें जो कहता है: “बड़ी शक्ति के साथ बड़ी जिम्मेदारी आती है”।

यदि आपको यह पोस्ट पसंद आई तो मेरे न्यूज़लेटर की सदस्यता लेना न भूलें 🙂


  1. Ruby के grep मेथड में महारत: कोड उदाहरणों के साथ एक व्यावहारिक गाइड Ruby के grep मेथड में महारत: कोड उदाहरणों के साथ एक व्यावहारिक गाइड

    आइए grep मेथड के बारे में बात करते हैं। यह मेथड आपके लिए क्या कर सकता है? आप enumerable ऑब्जेक्ट्स को फ़िल्टर करने के लिए Grep का उपयोग कर सकते हैं, जैसे Arrays और Ranges। "लेकिन select पहले से ही ऐसा करता है!" हाँ, लेकिन grep अलग तरीके से काम करता है और अलग परिणाम उत्पन्न करता है। आइए कुछ

  1. Ruby के Map मेथड में महारत: उदाहरणों के साथ एक व्यावहारिक गाइड Ruby के Map मेथड में महारत: उदाहरणों के साथ एक व्यावहारिक गाइड

    Map एक Ruby मेथड है जिसका उपयोग आप Arrays, Hashes और Ranges के साथ कर सकते हैं। map का मुख्य उपयोग डेटा को ट्रांसफॉर्म करना है। उदाहरण के लिए: स्ट्रिंग्स की एक सरणी दिए जाने पर, आप हर स्ट्रिंग पर जा सकते हैं और हर कैरेक्टर को UPPERCASE बना सकते हैं। या यदि आपके पास User ऑब्जेक्ट्स की एक सूची है... आ

  1. मेटाप्रोग्रामिंग की वास्तविक लागत: जो आपको जानना आवश्यक है मेटाप्रोग्रामिंग की वास्तविक लागत: जो आपको जानना आवश्यक है

    मेटाप्रोग्रामिंग बहुत फैंसी शब्द लगता है, लेकिन क्या यह अच्छा है? यह उपयोगी हो सकता है, लेकिन बहुत से लोग यह नहीं समझते कि मेटाप्रोग्रामिंग का उपयोग करने की कुछ लागतें हैं। बस ताकि हम एक ही पेज पर हों... मेटाप्रोग्रामिंग वास्तव में क्या है? मैं मेटाप्रोग्रामिंग को किसी भी मेथड का उपयोग करने के रूप म