Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

रूबी में ऑब्जेक्ट मार्शलिंग

इस लेख में, हम ऑब्जेक्ट मार्शलिंग में गोता लगाने जा रहे हैं। हम समझाएंगे कि यह क्या है, मार्शल मॉड्यूल को देखें, और फिर एक उदाहरण देखें। फिर हम एक कदम और गहराई तक जाएंगे और _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 द्वारा लौटाए गए डेटा को डीसेरियलाइज़ करना विधि
  • पुनर्गठित मूल वस्तु को तुरंत चालू करना

निष्कर्ष

अपनी आवश्यकताओं के आधार पर, आप उच्च या निम्न क्रमांकन/डिसेरिएलाइज़ेशन रणनीति को लागू करने का निर्णय ले सकते हैं। ऐसा करने के लिए, आप उचित मार्शल हुक विधियों के साथ मार्शल मॉड्यूल का उपयोग कर सकते हैं।

वोइला!


  1. रूबी में लैम्ब्डा का उपयोग करना

    ब्लॉक रूबी का इतना महत्वपूर्ण हिस्सा हैं, उनके बिना भाषा की कल्पना करना मुश्किल है। लेकिन लैम्ब्डा? लैम्ब्डा को कौन प्यार करता है? आप एक का उपयोग किए बिना वर्षों तक जा सकते हैं। वे लगभग पुराने जमाने के अवशेष की तरह लगते हैं। ...लेकिन यह बिल्कुल सच नहीं है। एक बार जब आप उनकी थोड़ी जांच कर लेते हैं त

  1. रूबी में 9 नई सुविधाएँ 2.6

    रूबी का एक नया संस्करण नई सुविधाओं और प्रदर्शन में सुधार के साथ आ रहा है। क्या आप परिवर्तनों के साथ बने रहना चाहेंगे? आइए एक नज़र डालते हैं! अंतहीन रेंज रूबी 2.5 और पुराने संस्करण पहले से ही अंतहीन श्रेणी के एक रूप का समर्थन करते हैं (Float::INFINITY के साथ) ), लेकिन रूबी 2.6 इसे अगले स्तर पर ले

  1. रूबी फ्रीज विधि - वस्तु परिवर्तनशीलता को समझना

    किसी वस्तु के परिवर्तनशील होने का क्या अर्थ है? फैंसी शब्दों को भ्रमित न होने दें, “परिवर्तनशीलता ” का सीधा सा मतलब है कि किसी वस्तु की आंतरिक स्थिति को बदला जा सकता है। जमे हुए . को छोड़कर, यह सभी वस्तुओं का डिफ़ॉल्ट है , या वे जो विशेष वस्तुओं की सूची का हिस्सा हैं। दूसरे शब्दों में, रूबी में सभ