इस लेख में, हम ऑब्जेक्ट मार्शलिंग में गोता लगाने जा रहे हैं। हम समझाएंगे कि यह क्या है, मार्शल मॉड्यूल को देखें, और फिर एक उदाहरण देखें। फिर हम एक कदम और गहराई तक जाएंगे और _dump . की तुलना करेंगे और self._load तरीके। चलो चलें!
ऑब्जेक्ट मार्शलिंग क्या है?
जब आप कोड लिख रहे होते हैं, तो हो सकता है कि आप किसी ऑब्जेक्ट को सहेजना और उसे किसी अन्य प्रोग्राम में ट्रांसमिट करना चाहें या अपने अगले प्रोग्राम निष्पादन में उसका पुन:उपयोग करना चाहें। उदाहरण के लिए, साइडकीक में ऑब्जेक्ट मार्शलिंग का उपयोग किया जाता है; जब रूबी ऑन रेल्स एप्लिकेशन में साइडकीक जॉब को एनक्यू किया जाता है, तो इस जॉब का एक सीरियलाइजेशन--जो एक ऑब्जेक्ट से ज्यादा कुछ नहीं है--रेडिस में डाला जाता है। साइडकीक प्रक्रिया तब इस JSON को deserialize करने और JSON से मूल कार्य का पुनर्गठन करने में सक्षम है।
कंप्यूटर प्रोग्रामिंग में, किसी वस्तु के क्रमांकन और अक्रमांकन की इस प्रक्रिया को हम आमतौर पर ऑब्जेक्ट मार्शलिंग कहते हैं। . अब, आइए देखें कि रूबी ऑब्जेक्ट मार्शलिंग को संभालने के लिए मूल रूप से क्या प्रदान करती है।
मार्शल मॉड्यूल
चूंकि रूबी पूरी तरह से ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग भाषा है, यह Marshall का उपयोग करके वस्तुओं को क्रमबद्ध और संग्रहीत करने का एक तरीका प्रदान करती है। अपने मानक पुस्तकालय में मॉड्यूल। यह आपको किसी ऑब्जेक्ट को एक बाइट स्ट्रीम में क्रमबद्ध करने की अनुमति देता है जिसे किसी अन्य रूबी प्रक्रिया में संग्रहीत और deserialized किया जा सकता है।
तो, आइए एक स्ट्रिंग को क्रमबद्ध करें और क्रमबद्ध वस्तु पर करीब से नज़र डालें।
hello_world = 'hello world!'
serialized_string = Marshal.dump(hello_world) # => "\x04\bI\"\x11hello world!\x06:\x06ET"
serialized_string.class # => String
deserialized_hello_world = Marshal.load(serialized_string) # => "hello world!"
hello_world.object_id # => 70204420126020
deserialized_hello_world.object_id # => 70204419825700
फिर हम Marshal.dump . को कॉल करते हैं हमारे स्ट्रिंग को क्रमबद्ध करने के लिए मॉड्यूल विधि। हम serialized_string . में रिटर्न वैल्यू को स्टोर करते हैं - जिसमें हमारी क्रमबद्ध स्ट्रिंग होती है चर। इस स्ट्रिंग को एक फ़ाइल में संग्रहीत किया जा सकता है और फ़ाइल को किसी अन्य प्रक्रिया में मूल ऑब्जेक्ट को पुनर्गठित करने के लिए पुन:उपयोग किया जा सकता है। फिर हम Marshal.load . को कॉल करते हैं मूल वस्तु को बाइट स्ट्रीम से पुनर्गठित करने की विधि।
हम देख सकते हैं कि इस ताज़ा पुनर्गठित स्ट्रिंग में एक अलग object_id है hello_world . की तुलना में स्ट्रिंग, जिसका अर्थ है कि यह एक अलग वस्तु है, लेकिन इसमें एक ही डेटा है।
बहुत अच्छा! लेकिन कैसा है Marshall मॉड्यूल स्ट्रिंग का पुनर्निर्माण करने में सक्षम है? और, क्या होगा यदि मैं इस पर नियंत्रण रखना चाहता हूं कि कौन सी विशेषताओं को क्रमबद्ध और deserialize करना है?
ऑब्जेक्ट मार्शलिंग का एक ठोस उदाहरण
इन सवालों का जवाब देने के लिए, आइए User नामक कस्टम संरचना पर एक मार्शलिंग रणनीति लागू करें। ।
User = Struct.new(:fullname, :age, :roles)
user = User.new('Mehdi Farsi', 42, [:admin, :operator])
User संरचना 3 विशेषताओं को परिभाषित करती है:fullname , age , और roles . इस उदाहरण के लिए हमारे पास एक व्यवसाय नियम है जहां हम केवल तभी क्रमबद्ध करते हैं जब यह निम्नलिखित मानदंडों से मेल खाता हो:
fullnameइसमें 64 से कम वर्ण हैंrolesसरणी में:adminशामिल नहीं है भूमिका
ऐसा करने के लिए, हम एक User#marshal_dump . को परिभाषित कर सकते हैं हमारी कस्टम क्रमांकन रणनीति को लागू करने की विधि। जब हम Marshal.dump . का आह्वान करेंगे तो इस विधि को कॉल किया जाएगा User . के उदाहरण के साथ विधि पैरामीटर के रूप में संरचना। आइए इस विधि को परिभाषित करें:
User = Struct.new(:age, :fullname, :roles) do
def marshal_dump
{}.tap do |result|
result[:age] = age
result[:fullname] = fullname if fullname.size <= 64
result[:roles] = roles unless roles.include? :admin
end
end
end
user = User.new(42, 'Mehdi Farsi', [:admin, :operator])
user_dump = Marshal.dump(user) # 'in User#marshal_dump'
user_dump # => "\x04\bU:\tUser{\a:\bageI\"\x10Mehdi Farsi\x06:\x06ET:\rfullnamei/"
उपरोक्त उदाहरण में, हम देख सकते हैं कि हमारा User#marshal_dump विधि को तब कहा जाता है जब हम Marshal.dump(user) का आह्वान करते हैं। user_dump वेरिएबल में वह स्ट्रिंग है जो हमारे User . का क्रमांकन है उदाहरण।
अब जब हमारे पास अपना डंप है, तो इसे अपने उपयोगकर्ता के पुनर्गठन के लिए deserialize करें। ऐसा करने के लिए, हम एक User#marshal_load . परिभाषित करते हैं विधि जो एक User . की अक्रमांकन रणनीति को लागू करने के प्रभारी है डंप।
तो चलिए इस तरीके को परिभाषित करते हैं।
User = Struct.new(:age, :fullname, :roles) do
def marshal_dump
{}.tap do |result|
result[:age] = age
result[:fullname] = fullname if fullname.size <= 64
result[:roles] = roles unless roles.include? :admin
end
end
def marshal_load(serialized_user)
self.age = serialized_user[:age]
self.fullname = serialized_user[:fullname]
self.roles = serialized_user[:roles] || []
end
end
user = User.new(42, 'Mehdi Farsi', [:admin, :operator])
user_dump = Marshal.dump(user) # 'in User#marshal_dump'
user_dump # => "\x04\bU:\tUser{\a:\bagei/:\rfullnameI\"\x10Mehdi Farsi\x06:\x06ET"
original_user = Marshal.load(user_dump) # 'in User#marshal_load'
original_user # => #<struct User age=42, fullname="Mehdi Farsi", roles=[]>
उपरोक्त उदाहरण में, हम देख सकते हैं कि हमारी User#marshal_load method जब हम Marshal.load(user_dump) . का आह्वान करते हैं तो उसे कॉल किया जाता है . original_user वेरिएबल में एक स्ट्रक्चर होता है जो हमारे यूजर इंस्टेंस का पुनर्गठन होता है।
ध्यान दें कि original_user.roles user.roles के समान नहीं है क्रमांकन के दौरान से सरणी, user.roles :admin . शामिल है भूमिका। तो user.roles user_dump में क्रमबद्ध नहीं किया गया था चर।
_dump और self._load तरीके
जब Marshal.dump और Marshal.load लागू किया जाता है, इन विधियों को marshal_dump . कहते हैं और marshal_load ऑब्जेक्ट पर विधियों को इन विधियों के पैरामीटर के रूप में पारित किया गया।
लेकिन, क्या होगा अगर मैं आपको बता दूं कि Marshal.dump और Marshal.load विधियाँ _dump . नामक दो अन्य विधियों को कॉल करने का प्रयास करती हैं और self._load पैरामीटर के रूप में पारित वस्तु पर?
_डंप विधि
marshal_dump . के बीच अंतर और _dump तरीके हैं:
_dump. का उपयोग करते समय आपको क्रमांकन रणनीति को निचले स्तर पर संभालना होगा method — आपको एक स्ट्रिंग वापस करने की आवश्यकता है जो क्रमबद्ध करने के लिए डेटा का प्रतिनिधित्व करती है- द
marshal_dumpविधि_dumpसे अधिक प्राथमिकता लेती है यदि दोनों परिभाषित हैं
आइए निम्नलिखित उदाहरण पर एक नजर डालते हैं:
User = Struct.new(:age, :fullname, :roles) do
def _dump level
[age, fullname].join(':')
end
end
user = User.new(42, 'Mehdi Farsi', [:admin, :operator])
Marshal.dump(user) # => "\x04\bIu:\tUser\x1342:Mehdi Farsi\x06:\x06EF"
User#_dump में विधि, हमें क्रमबद्धता वस्तु को तत्काल और वापस करना होगा--वह स्ट्रिंग जो आपके क्रमांकन का प्रतिनिधित्व करती है।
निम्नलिखित उदाहरण में, हम User#marshal_dump . को परिभाषित करते हैं और User#_dump विधियाँ और एक स्ट्रिंग लौटाएँ यह देखने के लिए कि कौन सी विधि कहलाती है
User = Struct.new(:age, :fullname, :roles) do
def marshal_dump
'in User#marshal_dump'
end
def _dump level
'in User#_dump'
end
end
user = User.new(42, 'Mehdi Farsi', [:admin, :operator])
user_dump = Marshal.dump(user) # "in User#marshal_dump"
हम देख सकते हैं कि केवल User#marshal_dump कहा जाता है, भले ही वे दोनों परिभाषित हों।
स्वयं._लोड विधि
अब, आइए marshal_load को देखें और _load तरीके।
marshal_load . के बीच अंतर और _load तरीके हैं:
_load. का उपयोग करते समय आपको निचले स्तर पर अक्रमांकन रणनीति को संभालने की आवश्यकता होती है method — आप मूल वस्तु को तुरंत चालू करने के प्रभारी हैं।- द
marshal_loadजब_self.loadविधि क्रमबद्ध स्ट्रिंग को एक तर्क के रूप में लेती है। - द
marshal_loadविधि एक उदाहरण विधि है जबself._loadएक वर्ग विधि है।
आइए निम्नलिखित उदाहरण पर एक नज़र डालें:
User = Struct.new(:age, :fullname, :roles) do
def _dump level
[age, fullname].join(':')
end
def self._load serialized_user
user_info = serialized_user.split(':')
new(*user_info, Array.new)
end
end
user = User.new(42, 'Mehdi Farsi', [:admin, :operator])
user_dump = Marshal.dump(user)
user_dump # => "\x04\bIu:\tUser\x1342:Mehdi Farsi\x06:\x06EF"
original_user = Marshal.load(user_dump)
original_user # => #<struct User age="Mehdi Farsi", fullname=42, roles=[]>
User._load . में विधि:
- हम
User#_dump. द्वारा लौटाए गए स्ट्रिंग को डिसेरिएलाइज़ करते हैं विधि - हम एक नए
Userको तुरंत चालू करते हैं deserialized जानकारी पास करके
हम देख सकते हैं कि हम अपने मूल उपयोगकर्ता को पुनर्गठित करने के लिए उपयोग की जाने वाली वस्तु को आवंटित और तत्काल करने के प्रभारी हैं।
तो Marshal.load marshal_load . के साथ मिलकर पुनर्गठित मूल वस्तु को तत्काल करने का ख्याल रखता है। फिर यह marshal_load . को कॉल करता है क्रमबद्ध वस्तु के साथ विधि को ताज़ा तात्कालिक वस्तु पर तर्क के रूप में पारित किया गया।
इसके विपरीत, Marshal.load . को कॉल करें _load . के साथ युग्मित self._load करने देता है वर्ग विधि का प्रभारी होना चाहिए:
_dumpद्वारा लौटाए गए डेटा को डीसेरियलाइज़ करना विधि- पुनर्गठित मूल वस्तु को तुरंत चालू करना
निष्कर्ष
अपनी आवश्यकताओं के आधार पर, आप उच्च या निम्न क्रमांकन/डिसेरिएलाइज़ेशन रणनीति को लागू करने का निर्णय ले सकते हैं। ऐसा करने के लिए, आप उचित मार्शल हुक विधियों के साथ मार्शल मॉड्यूल का उपयोग कर सकते हैं।
वोइला!