आपने पहले रूबी मेटाप्रोग्रामिंग के बारे में पढ़ा होगा।
लेकिन…
यह थोड़ा भ्रमित करने वाला हो सकता है अगर आपके पास कुछ विशिष्ट उदाहरण न हों।
इसलिए इस लेख में:
हम कुछ लोकप्रिय ओपन-सोर्स प्रोजेक्ट्स को देखने जा रहे हैं जो रूबी मेटाप्रोग्रामिंग का उपयोग करते हैं।
जैसे प्रोजेक्ट्स:
- रेल्स
- सिनात्रा
- पेपरक्लिप जेम
उन सभी में मेटाप्रोग्रामिंग के किसी न किसी रूप का उपयोग होता है।
चलिए कोड पर चलते हैं और पता लगाते हैं कि वे वास्तव में क्या कर रहे हैं!
रेल्स उदाहरण
रेल्स मेटाप्रोग्रामिंग का भारी उपयोग करता है, इसलिए यह शुरू करने के लिए एक अच्छी जगह है।
उदाहरण के लिए:
जब आप अपने रेल्स ऐप में वर्तमान वातावरण की जांच करना चाहते हैं, तो आप निम्न जैसा कुछ करते हैं।
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 ऑब्जेक्ट बनाता है और इंस्टेंस वेरिएबल सेट करता है।
यहां मूल स्रोत कोड है।
निष्कर्ष
जैसा कि आपने देखा, मेटाप्रोग्रामिंग एक बहुत शक्तिशाली और लचीली तकनीक है, लेकिन जब भी आप इसके लिए पहुंचना चाहें तो उस उद्धरण को याद रखें जो कहता है: “बड़ी शक्ति के साथ बड़ी जिम्मेदारी आती है”।
यदि आपको यह पोस्ट पसंद आई तो मेरे न्यूज़लेटर की सदस्यता लेना न भूलें 🙂