यदि आपने पहले कभी शोधन का उपयोग नहीं किया है, तो आप शायद आश्चर्यचकित हैं। आपने सुना होगा कि मंकी पैचिंग को बदलने के लिए शोधन शुरू किए गए थे। तो आप उम्मीद कर सकते हैं कि आप ActiveSupport के hours
जैसे कुछ को लागू करने में सक्षम होंगे विधि:
module TimeExtension
refine Fixnum do
def hours
self * 60
end
end
end
class MyFramework
using TimeExtension
end
class MyApp < MyFramework
def index
1.hours
end
end
MyApp.new.index # undefined method `hours' for 1:Fixnum (NoMethodError)
यदि आप ऊपर दिए गए कोड को चलाते हैं, तो आप पाएंगे कि यह काम नहीं करता है। तो क्या देता है?
कई अन्य महान विचारों की तरह, शोधन की मूल अवधारणा को भी बदलना पड़ा ताकि इसे कठोर वास्तविकता के साथ काम किया जा सके।
ऊपर हमने जो कोड देखा, उसमें आश्चर्यजनक व्यवहार इनमें से किसी एक बदलाव के कारण होता है। विशेष रूप से, वह नियम जो कहता है कि परिशोधन शाब्दिक रूप से दायरे में हैं।
लेक्सिकल स्कोपिंग क्या है?
जब हम कहते हैं कि कुछ लेक्सिकल है, तो इसका मतलब है कि टेक्स्ट के साथ क्या करना है - स्क्रीन पर कोड उस कोड के विपरीत है।
यदि दो पंक्तियों को शाब्दिक रूप से स्कोप किया जाता है, तो इसका सीधा सा अर्थ है कि वे एक ही कोड ब्लॉक के भीतर होती हैं - इस बात की परवाह किए बिना कि वह कोड ब्लॉक किस पर मूल्यांकन कर सकता है।
इसके बारे में बात करने की तुलना में एक उदाहरण देखना बहुत आसान है:
class B
# x and y share the same lexical scope
x = 1
y = 1
end
class B
# z has a different lexical scope from x and y, even though it's in the same class.
z = 3
end
शोधन शाब्दिक रूप से दायरे में हैं
जब हम उपयोग करने वाले कीवर्ड के साथ एक शोधन लागू करते हैं, तो शोधन केवल शाब्दिक दायरे में ही दिखाई देता है।
यहाँ एक उदाहरण दिया गया है जो दिखा रहा है कि मेरा क्या मतलब है:
module TimeExtension
refine Fixnum do
def hours
self * 60
end
end
end
class MyApp
using TimeExtension
def index
1.hours
end
end
class MyApp
def show
2.hours
end
end
MyApp.new.show # undefined method `hour' for 1:Fixnum (NoMethodError)
भले ही दोनों index
और show
विधियां एक ही वर्ग का हिस्सा हैं, केवल index
विधि के पास परिशोधन तक पहुंच है, क्योंकि केवल यह using
. के साथ शाब्दिक दायरे को साझा करता है बयान।
यह शायद थोड़ा अजीब लगता है, क्योंकि रूबी में बाकी सब कुछ गतिशील रूप से स्कॉप्ड है। जब आप किसी क्लास में कोई मेथड जोड़ते हैं, तो क्लास डेफिनिशन से बाहर निकलने पर मेथड वहीं रहता है। लेकिन ऐसा नहीं है कि शोधन कैसे काम करता है।
यह कई परिणाम हैं जो पहली बार में स्पष्ट नहीं हो सकते हैं।
आप एक शोधन विधि को गतिशील रूप से लागू नहीं कर सकते हैं
क्योंकि send
विधि को उसी कोड ब्लॉक में परिभाषित नहीं किया गया है जिसमें आपका उपयोग कथन शामिल है, यह परिशोधन नहीं देख सकता है।
तो यह काम नहीं करता:
class MyApp
using TimeExtension
def index
1.send(:hours)
end
end
आप किसी शोधन पद्धति के अस्तित्व को क्वेरी नहीं कर सकते हैं
respond_to?
विधि समान कोड ब्लॉक के भीतर भी नहीं है। तो यह उसी कारण से काम नहीं करता है जिस कारण send
विधि नहीं है।
class MyApp
using TimeExtension
def index
1.respond_to?(:hours)
end
end
निष्कर्ष
मुझे आशा है कि इससे कुछ भ्रम दूर हो जाएगा जो मैंने देखा है कि लोगों के पास परिशोधन है। वे निश्चित रूप से रूबी की एक संभावित उपयोगी विशेषता हैं, लेकिन यदि आपने उन्हें पहले कभी उपयोग नहीं किया है तो वे थोड़ा मुश्किल हो सकते हैं।