रूबी में कोड लोडर्स - Zeitwerk को समझना
Zeitwerk के साथ, आप यह जानकर अपनी प्रोग्रामिंग को सुव्यवस्थित कर सकते हैं कि क्लासेस और मॉड्यूल्स हर जगह उपलब्ध हैं।
कोड लोडर्स क्या हैं?
कोड लोडर्स डेवलपर्स को classes और modules को अलग-अलग फाइलों और फोल्डर्स में परिभाषित करने और उन्हें कोडबेस में पूरे स्थान पर उपयोग करने की अनुमति देते हैं बिना उन्हें स्पष्ट रूप से आवश्यकता के। रेल्स एक ऐसे सॉफ्टवेयर का अच्छा उदाहरण है जो कोड लोडर्स का उपयोग करता है। रेल्स में प्रोग्रामिंग के लिए मॉडल्स को कंट्रोलर्स में उपयोग करने से पहले उन्हें लोड करने के लिए स्पष्ट require कॉल की आवश्यकता नहीं होती है। वास्तव में, रेल्स 6 में, app डायरेक्टरी में सब कुछ ऐप बूट पर ऑटो-लोड होता है, कुछ अपवादों के साथ।
जबकि यह सोचना आसान है कि कोड लोडिंग require के कॉल करने के बारे में है, यह इतना सरल नहीं है। कोड लोडिंग को आगे तीन भागों में विभाजित किया जा सकता है, निम्नानुसार।
- ऑटो लोडिंग: इसका मतलब है कि कोड आवश्यकतानुसार ऑन-द-फ्लाई लोड होता है। उदाहरण के लिए, रेल्स में,
rails sचलाने से सभी मॉडल्स, कंट्रोलर्स आदि लोड नहीं होते। लेकिन, मॉडलUserकी पहली हिट पर, यह मॉडल को खोजने और उपयोग करने के लिए ऑटो लोडिंग मैकेनिज्म चलाता है। यह ऑटो लोडिंग की क्रिया है। इसके हमारे विकास वातावरण के लिए कुछ फायदे हैं, क्योंकि हमारे पास तेज़ ऐप औरrails consoleस्टार्टअप समय होते हैं।Rails.config.autoload_pathऑटो-लोड होने वाले पथों को नियंत्रित करता है। - ईगर लोडिंग: इसका मतलब है कि कोड ऐप स्टार्टअप पर मेमोरी में लोड होता है और कॉन्स्टेंट्स के कॉल होने से पहले इसकी आवश्यकता होने की प्रतीक्षा नहीं करता। रेल्स में, कोड प्रोडक्शन में ईगर लोड होता है। उपरोक्त व्याख्या से, प्रोडक्शन में कोड को ऑटो-लोड करने से प्रतिक्रिया समय धीमा होगा, क्योंकि प्रत्येक कॉन्स्टेंट को ऑन-द-फ्लाई आवश्यकता होगी।
Rails.config.eager_load_pathsईगर लोड होने वाले पथों को नियंत्रित करता है। - रिलोडिंग: कोड लोडर
autoload_pathमें फाइलों में परिवर्तनों को लगातार देखता है और जब भी कोई परिवर्तन देखता है तो फाइलों को रीलोड करता है। रेल्स में, यह विकास में काफी उपयोगी हो सकता है, क्योंकि यह हमेंrails sचलाने और रेल्स सर्वर को पुनरारंभ करने की आवश्यकता के बिना एक साथ परिवर्तन करने में सक्षम बनाता है। यह रिलोडिंग की क्रिया है।
हम आसानी से देख सकते हैं कि इन अवधारणाओं में से अधिकांश विकसित की गई हैं और रेल्स में रहती हैं। Zeitwerk इसे बदलता है! Zeitwerk हमें सभी कोड लोडिंग एक्शन को किसी भी रूबी प्रोजेक्ट में लाने में सक्षम बनाता है।
Zeitwerk क्या है?
Zeitwerk रूबी के लिए एक कुशल और थ्रेड-सेफ कोड लोडर है और इसका उपयोग किसी भी रूबी प्रोजेक्ट में किया जा सकता है, जिसमें वेब फ्रेमवर्क (रेल्स, हनामी, सिनात्रा), CLI टूल्स, और जेम्स शामिल हैं। इसके साथ, आप यह जानकर अपनी प्रोग्रामिंग को सुव्यवस्थित कर सकते हैं कि क्लासेस और मॉड्यूल्स हर जगह उपलब्ध हैं। पारंपरिक रूप से, रेल्स और कुछ अन्य जेम्स में इस कार्यक्षमता को सक्षम करने के लिए बिल्ट-इन कोड लोडर्स होते हैं। हालांकि, Zeitwerk इन अवधारणाओं को एक जेम में निकालता है और रूबीइस्ट्स को उन्हें अपने प्रोजेक्ट्स पर लागू करने की अनुमति देता है।
Zeitwerk इंस्टॉल करना
पहली चीज़ें पहले, हमें जेम इंस्टॉल करने की आवश्यकता है:
gem install zeitwerk # OR अपने Gemfile में
gem 'zeitwerk', '~> 2.4.0'
Zeitwerk कॉन्फिगर करना
तो आइए बुनियादी बातों से शुरू करते हैं:
require 'zeitwerk'
loader = Zeitwerk::Loader.new
...
loader.setup
उपरोक्त कोड एक लोडर इंस्टेंस को इंस्टेंटिएट करता है और setup को कॉल करता है। setup के कॉल के बाद, लोडर्स कोड लोड करने के लिए तैयार हैं। लेकिन, उससे पहले, loader पर सभी आवश्यक कॉन्फिगरेशन पहले से ही कवर किए जाने चाहिए। इस लेख में, मैं loader पर कुछ कॉन्फिगरेशन और आपके कोड को संरचित करने के लिए कन्वेंशन्स को कवर करूंगा।
- फाइल संरचना: Zeitwerk के काम करने के लिए, फाइलों और डायरेक्टरी नामों को उनके द्वारा परिभाषित मॉड्यूल्स और क्लास नामों से मेल खाना चाहिए। उदाहरण के लिए,
lib/my_gem.rb -> MyGem
lib/my_gem/foo.rb -> MyGem::Foo
lib/my_gem/bar_baz.rb -> MyGem::BarBaz
lib/my_gem/woo/zoo.rb -> MyGem::Woo::Zoo
- रूट नेमस्पेस: रूट नेमस्पेस वे डायरेक्टरी हैं जहां
Zeitwerkआपका कोड ढूंढ सकता है। जबmodulesऔरclassesको संदर्भित किया जाता है, तो Zeitwerk मेल खाने वाले फाइल नाम के साथ रूट नेमस्पेस में खोज करना जानता है। उदाहरण के लिए,
require 'zeitwerk'
loader = Zeitwerk::Loader.new
loader.push_dir("app/models")
loader.push_dir("app/controllers")
// निम्नानुसार मेल खाता है
app/models/user.rb -> User
app/controllers/admin/users_controller.rb -> Admin::UsersController
दो अलग-अलग उपयोग के मामलों के लिए रूट नेमस्पेस को परिभाषित करने के दो प्राथमिक तरीके हैं। डिफ़ॉल्ट तरीका नीचे दिखाया गया है:
// init.rb
require 'zeitwerk'
loader = Zeitwerk::Loader.new
loader.push_dir("#{__dir__}/bar")
...
loader.setup
// bar/foo.rb
class Foo; end
इसका मतलब है कि क्लास Foo को स्पष्ट Bar::Foo के बिना संदर्भित किया जा सकता है, क्योंकि bar डायरेक्टरी रूट नेमस्पेस के रूप में कार्य करती है। नेमस्पेस को परिभाषित करने का दूसरा तरीका push_dir के कॉल में नेमस्पेस को स्पष्ट रूप से बताना है:
// init.rb
require 'zeitwerk'
module Bar
end
loader = Zeitwerk::Loader.new
loader.push_dir("#{__dir__}/src", namespace: Bar)
loader.setup
// src/foo.rb
class Bar::Foo; end
इस कोड में कुछ बातें ध्यान देने योग्य हैं:
- मॉड्यूल
Barकोpush_dirद्वारा उपयोग किए जाने से पहले पहले ही परिभाषित किया गया था। यदि हम जिस मॉड्यूल का उपयोग करना चाहते हैं वह किसी थर्ड-पार्टी द्वारा परिभाषित है, तो एक साधारण require इसेpush_dirमें हमारे उपयोग से पहले परिभाषित कर देगा। push_dirस्पष्ट रूप से नेमस्पेसBarको निर्दिष्ट करता है।- फाइल
src/foo.rbनेBar::Fooको परिभाषित किया,Fooको नहीं, औरsrc/bar/foo.rbजैसी डायरेक्टरी बनाने की आवश्यकता नहीं थी।
स्वतंत्र कोड लोडर: डिज़ाइन द्वारा, Zeitwerk प्रत्येक प्रोजेक्ट या ऐप निर्भरता को अपने व्यक्तिगत प्रोजेक्ट ट्री को प्रबंधित करने की अनुमति देता है। इसका मतलब है कि प्रत्येक निर्भरता का कोड लोडिंग मैकेनिज्म उस निर्भरता द्वारा प्रबंधित किया जाता है। उदाहरण के लिए, रेल्स 6 में, Zeitwerk रेल्स ऐप के लिए कोड लोडिंग को संभालता है और प्रत्येक जेम निर्भरता को अपने स्वयं के प्रोजेक्ट ट्री को अलग से प्रबंधित करने की अनुमति देता है। एकाधिक कोड लोडर्स के बीच ओवरलैपिंग फाइलें होना एक त्रुटि स्थिति है।
ऑटोलोडिंग: उपरोक्त सेटअप के साथ, एक बार
setupका कॉल किए जाने पर, सभी क्लासेस और मॉड्यूल्स मांग पर उपलब्ध होंगे।रिलोडिंग: रिलोडिंग सक्षम करने के लिए,
loaderको स्पष्ट रूप से इसके लिए कॉन्फ़िगर किया जाना चाहिए। उदाहरण के लिए,
loader = Zeitwerk::Loader.new
...
loader.enable_reloading # setup से पहले ऑप्ट-इन करने की आवश्यकता है
loader.setup
...
loader.reload
loader.reload कॉल प्रोजेक्ट ट्री को ऑन-द-फ्लाई रीलोड करता है, और कोई भी नया परिवर्तन तुरंत दिखाई देता है। हालांकि, हमें अभी भी फाइल सिस्टम में परिवर्तनों का पता लगाने और loader.reload को कॉल करने के लिए एक आसपास के मैकेनिज्म की आवश्यकता है। एक सरल संस्करण नीचे दिखाया गया है:
require 'filewatcher'
loader = Zeitwerk::Loader.new
...
loader.enable_reloading
loader.setup
...
my_filewatcher = Filewatcher.new('lib/')
Thread.new(my_filewatcher) {|fw| fw.watch {|filename| loader.reload } }
रेल्स में Zeitwerk का उपयोग
Zeitwerk रेल्स 6.0 में डिफ़ॉल्ट रूप से सक्षम है। हालांकि, आप इससे ऑप्ट-आउट कर सकते हैं और रेल्स classic कोड लोडर का उपयोग कर सकते हैं।
# config/application.rb
config.load_defaults "6.0"
config.autoloader = :classic
जेम्स में Zeitwerk का उपयोग
Zeitwerk जेम्स के लिए एक सुविधाजनक मेथड प्रदान करता है, जब तक वे मानक जेम संरचना (lib/special_gem) का उपयोग करते हैं। इस सुविधा मेथड का उपयोग निम्नानुसार किया जा सकता है:
# lib/special_gem.rb
require 'zeitwerk'
module SpecialGem
end
loader = Zeitwerk::Loader.for_gem
loader.setup
मानक जेम संरचना के साथ, for_gem कॉल lib डायरेक्टरी को रूट नेमस्पेस के रूप में जोड़ता है, जिससे lib डायरेक्टरी में हर कोड को स्वचालित रूप से ढूंढा जा सके।
अधिक प्रेरणा के लिए, आप Zeitwerk का उपयोग करने वाले जेम्स देख सकते हैं:
- Karafka
- Jets
संदर्भ
रेल्स ऑटोलोडिंग - यह कैसे काम करता है, और जब यह नहीं करता
Zeitwerk