الوحدة Marshal في روبي

من موسوعة حسوب
اذهب إلى: تصفح، ابحث

تحوّل المكتبة Marshal مجموعات من كائنات روبي إلى مجرى من البايتات (byte stream)، مما يسمح بتخزينها خارج البرنامج النصي النشط حاليًا. يمكن بعد ذلك قراءة تلك البيانات وإعادة إنشاء الكائنات الأصلية أنشئت منها.

تحتوي البيانات المرصوفة (Marshaled data) على أرقام الإصدار الرئيسية والثانوية مخزنةً مع معلومات الكائن. في الاستخدام العادي، تُحمّل فقط البيانات التي لها نفس رقم الإصدار الرئيسي، ورقم الإصدار الثانوي المساوي أو الأقل منه. وفي حال ضبط قيمة الراية "verbose" (عادةً باستخادم ‎-d أو ‎-v أو ‎-w أو ‎-verbose) يجب أن تتطابق الأرقام الرئيسية والثانوية تمامًا. إصدارات Marshal مستقلة عن إصدار روبي المستخدم. يمكنك استخلاص رقم الإصدار عن طريق قراءة أول بايتين من البيانات المرصوفة.
str = Marshal.dump("thing")
RUBY_VERSION   #=> "1.9.0"
str[0].ord     #=> 4
str[1].ord     #=> 8
لا يمكن تفريغ بعض الكائنات: في حال محاولة تفريغ كائنات تتضمن ارتباطات (bindings) أو إجراءات (procedure) أو توابع، أو كائنات IO، أو كائنات أحادية (singleton)، فسيطلق الخطأ TypeError.

إن كنت تريد تسلسلًا (serialization) مخصصًا (مثل إذا كنت تريد إجراء التسلسل وفق تنسيق معين)، أو إذا كان الصنف يحوي كائنات غير قابلة للتسلسل، فيمكنك إعداد قواعد التسلسل الخاصة بك.

هناك طريقتان للقيام بذلك، يمكن للكائنات أن تعرّف إما marshal_dump و marshal_load أو ‎_dump و ‎_load. يملك marshal_dump أولويةً على ‎_dump في حال تعريف كليهما. قد يُنتج marshal_dump سلاسل نصية أصغر.

تحسُّبات أمنية

يمكن للتابع load فك تسلسل (deserialize) أي صنف مُحمّل في عمليات روبي تقريبًا. في العديد من الحالات، يمكن أن يؤدي ذلك إلى تنفيذ التعليمات البرمجية عن بُعد إن حُملت البيانات المرصوفة (Marshal data) من مصدر غير موثوق به.

نتيجة لذلك، التابع load:: ليس مناسبًا ليكون تنسيقَ تسلسلٍ عامٍّ، ويجب ألا يتم تبديد (unmarshal) البيانات المُدخلة من قبل المستخدم أو غيرها من البيانات غير الموثوقة.

إذا كنت تريد فك تسلسل (deserialize) البيانات غير الموثوقة، فاستخدم JSON أو تنسيق تسلسل آخر لا يمكنه أن يحمّل إلا الأنواع "البدائية" البسيطة، مثل السلاسل النصية والمصفوفات وجداول Hash وما إلى ذلك. لا تسمح أبدًا لمدخلات المستخدم أن تحدد أنواعًا عشوائيةً لفك التسلسل.

التابع marshal_dump والتابع marshal_load

عند تفريغ (dumping) كائن، سيتم استدعاء التابع marshal_dump. يجب أن يعيد التابع marshal_dump نتيجةً تحتوي على المعلومات الضرورية للتابع marshal_load لإعادة إنشاء الكائن. النتيجة يمكن أن تكون أي كائن.

عند تحميل كائن تم تفريغه باستخدام marshal_dump، يتم أولاً تحديد الكائن، ثم يُستدعَى التابع marshal_load وتُمرّر إليه النتيجة المُعادة من التابع marshal_dump. يجب أن يعيد التابع marshal_load إنشاء الكائن انطلاقًا من المعلومات المُتضمنة في النتيجة.

اطلع على المثال التالي:
class MyObj
  def initialize name, version, data
    @name    = name
    @version = version
    @data    = data
  end

  def marshal_dump
    [@name, @version]
  end

  def marshal_load array
    @name, @version = array
  end
end

التابع ‎_dump والتابع ‎_load

استخدم التابعين ‎_dump و ‎_load عندما تريد تحديد الكائن الذي تود استعادته بنفسك.

عند تفريغ كائن، يُستدعى التابع ‎_dump مع تمرير عدد صحيح إليه يشير إلى العمق الأقصى للكائنات التى ستُفرّغ (القيمة ‎ -‎‎1تعني يجب عليك تعطيل التحقق من العمق). يجب أن يعيد التابع ‎ _dumpسلسلةً نصيةً تحتوي على المعلومات الضرورية لإعادة إنشاء الكائن.

يأخذ الصنف method_load سلسلةً نصيةً ويستخدمها لإعادة كائن من نفس الصنف.

إليك المثال التالي:
class MyObj
  def initialize name, version, data
    @name    = name
    @version = version
    @data    = data
  end

  def _dump level
    [@name, @version].join ':'
  end

  def self._load args
    new(*args.split(':'))
  end
end
لما كان التابع dump يعيد سلسلة نصية، يمكنك جعل التابع have_dump يعيد سلسلة مرصوفة ‎‏ (Marshal string)،

الثوابت

MAJOR_VERSION

يمثِّل الإصدار الرئيسي.

MINOR_VERSION

يمثِّل الإصدار الثانوي.

توابع الصنف العامة (Public Class Methods)

dump

يُسلسل (Serializes) الكائن المعطى وجميع الكائنات المنحدرة منه (descendant objects). في حال تمرير كائن من النوع IO، فستُكتب البيانات المُسَلسلة فيه، وإلا فستُعاد البياناتكسلسلة نصية.

load

يعيد نتيجة تحويل البيانات المُسلسلة (serialized) في المصدر إلى كائن روبي (ربما مع كائنات ثانوية [subordinate objects] مرتبطة به).

restore

يعيد نتيجة تحويل البيانات المُسلسلة (serialized) في المصدر إلى كائن روبي (ربما مع كائنات ثانوية [subordinate objects] مرتبطة به).

مصادر