কম্পিউটার

রুবিতে অবজেক্ট মার্শালিং

এই নিবন্ধে, আমরা অবজেক্ট মার্শালিং এ ডুব দিতে যাচ্ছি। আমরা এটি কী তা ব্যাখ্যা করব, মার্শাল মডিউলটি দেখুন এবং তারপরে একটি উদাহরণ দিয়ে যান। তারপর আমরা আরও এক ধাপ গভীরে যাব এবং _dump তুলনা করব এবং self._load পদ্ধতি চলুন!

অবজেক্ট মার্শালিং কি?

আপনি যখন কোড লিখছেন, আপনি একটি বস্তু সংরক্ষণ করতে এবং এটি অন্য প্রোগ্রামে প্রেরণ করতে বা আপনার পরবর্তী প্রোগ্রাম সম্পাদনে এটি পুনরায় ব্যবহার করতে চাইতে পারেন। সিডেকিকে অবজেক্ট মার্শালিং ব্যবহার করা হয়, উদাহরণস্বরূপ; যখন একটি Sidekiq কাজ একটি Ruby on Rails অ্যাপ্লিকেশনে সারিবদ্ধ করা হয়, তখন এই কাজের একটি ক্রমিককরণ - যা একটি বস্তু ছাড়া আর কিছুই নয় - Redis-এ ঢোকানো হয়। Sidekiq প্রক্রিয়া তারপর এই JSON ডিসিরিয়ালাইজ করতে সক্ষম হয় এবং JSON থেকে মূল কাজ পুনর্গঠন করে।

কম্পিউটার প্রোগ্রামিং-এ, কোনো বস্তুর সিরিয়ালাইজেশন এবং ডিসিরিয়ালাইজেশনের এই প্রক্রিয়াটিকে আমরা সাধারণত অবজেক্ট মার্শালিং বলি। . এখন, অবজেক্ট মার্শালিং পরিচালনা করার জন্য রুবি নেটিভভাবে কী প্রদান করে তা দেখা যাক।

মার্শাল মডিউল

যেহেতু রুবি একটি সম্পূর্ণ অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং ল্যাঙ্গুয়েজ, তাই এটি Marshall ব্যবহার করে অবজেক্টকে সিরিয়ালাইজ এবং স্টোর করার একটি উপায় প্রদান করে। তার স্ট্যান্ডার্ড লাইব্রেরিতে মডিউল। এটি আপনাকে একটি বাইট স্ট্রীমে একটি বস্তুকে সিরিয়ালাইজ করার অনুমতি দেয় যা অন্য রুবি প্রক্রিয়ায় সংরক্ষণ এবং ডিসিরিয়ালাইজ করা যায়।

সুতরাং, আসুন একটি স্ট্রিংকে সিরিয়ালাইজ করি এবং সিরিয়ালাইজড অবজেক্টটি ঘনিষ্ঠভাবে দেখে নেওয়া যাক।

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 মডিউল স্ট্রিং পুনর্গঠন করতে সক্ষম? এবং, যদি আমি কোন বৈশিষ্ট্যগুলিকে সিরিয়ালাইজ এবং ডিসিরিয়ালাইজ করতে চাই তার উপর নিয়ন্ত্রণ রাখতে চাই?

অবজেক্ট মার্শালিং এর একটি কংক্রিট উদাহরণ

এই প্রশ্নের উত্তর দেওয়ার জন্য, আসুন User নামের একটি কাস্টম স্ট্রাকটে একটি মার্শালিং কৌশল প্রয়োগ করি .

User = Struct.new(:fullname, :age, :roles)
 
user = User.new('Mehdi Farsi', 42, [:admin, :operator])

User struct 3টি বৈশিষ্ট্য সংজ্ঞায়িত করে:fullname , age , এবং roles . এই উদাহরণের জন্য আমাদের একটি ব্যবসায়িক নিয়ম রয়েছে যেখানে আমরা শুধুমাত্র তখনই সিরিয়ালাইজ করি যখন এটি নিম্নলিখিত মানদণ্ডের সাথে মেলে:

  • fullname 64টির কম অক্ষর রয়েছে
  • roles অ্যারেতে :admin নেই ভূমিকা

এটি করার জন্য, আমরা একটি User#marshal_dump সংজ্ঞায়িত করতে পারি আমাদের কাস্টম সিরিয়ালাইজেশন কৌশল বাস্তবায়নের পদ্ধতি। যখন আমরা Marshal.dump ব্যবহার করি তখন এই পদ্ধতিটি বলা হবে User এর উদাহরণ সহ পদ্ধতি struct পরামিতি হিসাবে। আসুন এই পদ্ধতিটি সংজ্ঞায়িত করি:

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 এর ক্রমিককরণ উদাহরণ।

এখন যেহেতু আমাদের ডাম্প আছে, আসুন আমাদের ব্যবহারকারীকে পুনর্গঠন করতে এটিকে ডিসিরিয়ালাইজ করি। এটি করার জন্য, আমরা একটি 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-এ সিরিয়ালাইজ করা হয়নি পরিবর্তনশীল।

_ডাম্প এবং স্বয়ং_লোড পদ্ধতি

যখন Marshal.dump এবং Marshal.load আহ্বান করা হয়, এই পদ্ধতিগুলিকে marshal_dump বলা হয় এবং marshal_load এই পদ্ধতির প্যারামিটার হিসাবে অবজেক্টের মেথড পাস করা হয়েছে।

কিন্তু, আমি যদি আপনাকে বলি যে Marshal.dump এবং Marshal.load পদ্ধতিগুলি _dump নামে অন্য দুটি পদ্ধতিকে কল করার চেষ্টা করে এবং self._load বস্তুতে প্যারামিটার হিসাবে পাস করা হয়েছে?

_ডাম্প পদ্ধতি

marshal_dump-এর মধ্যে পার্থক্য এবং _dump পদ্ধতি হল:

  • _dump ব্যবহার করার সময় আপনাকে একটি নিম্ন স্তরে সিরিয়ালাইজেশন কৌশল পরিচালনা করতে হবে পদ্ধতি—আপনাকে একটি স্ট্রিং ফেরত দিতে হবে যা সিরিয়ালাইজ করার জন্য ডেটা প্রতিনিধিত্ব করে
  • 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 ব্যবহার করার সময় আপনাকে নিম্ন স্তরে ডিসিরিয়ালাইজেশন কৌশলটি পরিচালনা করতে হবে পদ্ধতি—আপনি মূল বস্তুটি ইনস্ট্যান্ট করার দায়িত্বে আছেন।
  • 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. রুবিতে বিটওয়াইজ হ্যাক

  2. রুবিতে ল্যাম্বডাস ব্যবহার করা

  3. রুবি 2.6-এ 9টি নতুন বৈশিষ্ট্য

  4. রুবি ফ্রিজ পদ্ধতি - বস্তুর পরিবর্তনশীলতা বোঝা