रूबी में कोड लोडर - Zeitwerk को समझना
Zeitwerk के साथ, आप यह जानकर अपनी प्रोग्रामिंग को सुव्यवस्थित कर सकते हैं कि कक्षाएं और मॉड्यूल हर जगह उपलब्ध हैं।
कोड लोडर क्या हैं?
कोड लोडर डेवलपर्स को classes
define को परिभाषित करने देते हैं और modules
विभिन्न फाइलों और फ़ोल्डरों में और स्पष्ट रूप से उनकी आवश्यकता के बिना पूरे कोडबेस में उनका उपयोग करें। रेल सॉफ्टवेयर के एक टुकड़े का एक अच्छा उदाहरण है जो कोड लोडर का उपयोग करता है। रेल में प्रोग्रामिंग के लिए स्पष्ट require
की आवश्यकता नहीं है नियंत्रकों में उपयोग करने से पहले मॉडल लोड करने के लिए कॉल करें। वास्तव में, रेल 6 में, app
. में सब कुछ कुछ अपवादों के साथ, निर्देशिका ऐप बूट पर स्वतः लोड हो जाती है।
हालांकि यह सोचना आसान है कि कोड लोड करना require
. पर कॉल करना है , यह इतना आसान नहीं है। कोड लोडिंग को आगे तीन भागों में विभाजित किया जा सकता है, जो इस प्रकार है।
- स्वतः लोड हो रहा है: इसका मतलब है कि कोड आवश्यकतानुसार ऑन-द-फ्लाई लोड किया गया है। उदाहरण के लिए, रेल में
rails s
running चल रहा है सभी मॉडलों, नियंत्रकों आदि को लोड नहीं करता है लेकिन, मॉडल के पहले हिट परUser
, यह मॉडल को खोजने और उपयोग करने के लिए ऑटो लोडिंग तंत्र चलाता है। यह कार्रवाई में ऑटो लोडिंग है। हमारे विकास के माहौल के लिए इसके कुछ फायदे हैं, क्योंकि हमारे पास तेज़ ऐप औरrails console
. है स्टार्टअप समय।Rails.config.autoload_path
स्वतः लोड होने वाले पथों को नियंत्रित करता है। - उत्सुक लोड हो रहा है: इसका मतलब है कि ऐप स्टार्टअप पर कोड को मेमोरी में लोड किया जाता है और इसकी आवश्यकता होने से पहले स्थिरांक को कॉल करने की प्रतीक्षा नहीं करता है। रेल में, कोड उत्पादन में उत्सुक है। ऊपर दिए गए स्पष्टीकरण से, उत्पादन में ऑटोलोडिंग कोड के परिणामस्वरूप धीमी प्रतिक्रिया समय होगा, क्योंकि प्रत्येक स्थिरांक को ऑन-द-फ्लाई की आवश्यकता होगी।
Rails.config.eager_load_paths
उत्सुक लोड होने के पथ को नियंत्रित करता है। - पुनः लोड हो रहा है: कोड लोडर लगातार
autoload_path
. में फ़ाइलों में होने वाले परिवर्तनों को देख रहा है और किसी भी बदलाव को नोटिस करने पर फाइलों को फिर से लोड करता है। रेल में, यह विकास में काफी उपयोगी हो सकता है, क्योंकि यह हमेंrails s
चलाने में सक्षम बनाता है और साथ ही रेल सर्वर को पुनरारंभ करने की आवश्यकता के बिना परिवर्तन करें। यह क्रिया में पुनः लोड हो रहा है।
हम आसानी से देख सकते हैं कि इनमें से अधिकतर अवधारणाएं विकसित की गई हैं और रेल में रहती हैं। Zeitwerk इसे बदलता है! Zeitwerk हमें किसी भी रूबी प्रोजेक्ट में सभी कोड लोडिंग एक्शन लाने में सक्षम बनाता है।
Zeitwerk क्या है?
Zeitwerk रूबी के लिए एक कुशल और थ्रेड-सुरक्षित कोड लोडर है और इसका उपयोग किसी भी रूबी प्रोजेक्ट में किया जा सकता है, जिसमें वेब फ्रेमवर्क (रेल, हनामी, सिनात्रा), क्ली टूल्स और रत्न शामिल हैं। इसके साथ, आप यह जानकर अपनी प्रोग्रामिंग को सुव्यवस्थित कर सकते हैं कि कक्षाएं और मॉड्यूल हर जगह उपलब्ध हैं। परंपरागत रूप से, रेल और कुछ इस कार्यक्षमता को सक्षम करने के लिए अन्य रत्नों में अंतर्निहित कोड लोडर हैं। हालांकि, Zeitwerk इन अवधारणाओं को एक रत्न में निकालता है और रूबीवादियों को इन अवधारणाओं को अपनी परियोजनाओं में लागू करने की अनुमति देता है।
Zeitwerk इंस्टॉल करना
सबसे पहले चीज़ें, हमें मणि स्थापित करने की आवश्यकता है:
gem install zeitwerk
# OR in your 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")
// matches as follows
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
. के बिना संदर्भित किया जा सकता है , क्योंकि बार निर्देशिका रूट नामस्थान के रूप में कार्य करती है। नेमस्पेस को परिभाषित करने का दूसरा तरीका यह है कि 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
. द्वारा उपयोग किए जाने से पहले ही परिभाषित किया गया था . यदि हम जिस मॉड्यूल का उपयोग करना चाहते हैं उसे किसी तृतीय-पक्ष द्वारा परिभाषित किया गया है, तो हमारे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 # you need to opt-in before 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 का उपयोग करना
रेल 6.0 में डिफ़ॉल्ट रूप से Zeitwerk सक्षम है। हालांकि, आप इससे ऑप्ट-आउट कर सकते हैं और रेल का उपयोग कर सकते हैं 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 का उपयोग करके रत्नों की जांच कर सकते हैं:
- कराफ्का
- जेट
संदर्भ
रेल ऑटोलोडिंग - यह कैसे काम करता है, और कब नहीं करता है
Zeitwerk