الفرق بين المراجعتين ل"Ruby/Marshal"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
سطر 1: سطر 1:
 
تحوّل المكتبة <code>Marshal</code> مجموعات من كائنات روبب إلى سلاسل بتات (byte stream)، مما يسمح بتخزينها خارج البرنامج النصي النشط حاليًا. ثم يمكن بعد ذلك قراءة تلك البيانات وإعادة إنشاء الكائنات الأصلية.   
 
تحوّل المكتبة <code>Marshal</code> مجموعات من كائنات روبب إلى سلاسل بتات (byte stream)، مما يسمح بتخزينها خارج البرنامج النصي النشط حاليًا. ثم يمكن بعد ذلك قراءة تلك البيانات وإعادة إنشاء الكائنات الأصلية.   
  
تحتوي البيانات المشحونة (Marshaled data) على أرقام إصدار رئيسية وثانوية مخزنة مع معلومات الكائن. في الاستخدام العادي ، تُحمّل فقط البيانات التي لها نفس رقم الإصدار الرئيسي، ورقم إصدار ثانوي مساوٍ أو أقل. في حال ضبط قيمة الراية "<code>verbose</code>" (عادةً باستخادم ‎<code>-d</code> أو ‎<code>-v</code> أو <code>‎-w</code> أو ‎<code>-verbose</code>) يجب أن تتطابق الأرقام الرئيسية والثانوية تمامًا. إصدارات <code>Marshal</code> مستقلة عن أرقام إصدار روبي المستخدم. يمكنك استخلاص رقم الإصدار عن طريق قراءة أول بتّتين من البيانات المشحونة. <syntaxhighlight lang="ruby">
+
تحتوي البيانات المرصوفة (Marshaled data) على أرقام إصدار رئيسية وثانوية مخزنة مع معلومات الكائن. في الاستخدام العادي ، تُحمّل فقط البيانات التي لها نفس رقم الإصدار الرئيسي، ورقم إصدار ثانوي مساوٍ أو أقل. في حال ضبط قيمة الراية "<code>verbose</code>" (عادةً باستخادم ‎<code>-d</code> أو ‎<code>-v</code> أو <code>‎-w</code> أو ‎<code>-verbose</code>) يجب أن تتطابق الأرقام الرئيسية والثانوية تمامًا. إصدارات <code>Marshal</code> مستقلة عن أرقام إصدار روبي المستخدم. يمكنك استخلاص رقم الإصدار عن طريق قراءة أول بتّتين من البيانات المشحونة.<syntaxhighlight lang="ruby">
 
str = Marshal.dump("thing")
 
str = Marshal.dump("thing")
 
RUBY_VERSION  #=> "1.9.0"
 
RUBY_VERSION  #=> "1.9.0"
سطر 11: سطر 11:
  
 
هناك طريقتان للقيام بذلك، يمكن للكائنات تعريف إما <code>marshal_dump</code> و <code>marshal_load</code> أو ‎<code>_dump</code> و ‎<code>_load</code>. سيكون لـ <code>marshal_dump</code> الأولوية على ‎<code>_dump</code> في حال تعريف كليهما. قد يُنتج <code>marshal_dump</code> سلاسل نصية أصغر.
 
هناك طريقتان للقيام بذلك، يمكن للكائنات تعريف إما <code>marshal_dump</code> و <code>marshal_load</code> أو ‎<code>_dump</code> و ‎<code>_load</code>. سيكون لـ <code>marshal_dump</code> الأولوية على ‎<code>_dump</code> في حال تعريف كليهما. قد يُنتج <code>marshal_dump</code> سلاسل نصية أصغر.
 +
==اعتبارات أمنية==
 +
يمكن للتابع <code>[[Ruby/Marshal/load|load]]</code> فك تسلسل (deserialize) تقريبا أي صنف مُحمّل في عمليات روبي. في العديد من الحالات، يمكن أن يؤدي ذلك إلى تنفيذ التعليمات البرمجية عن بُعد، إن حُملت بيانات <code>Marshal</code> من مصدر غير موثوق به.
  
== اعتبارات أمنية ==
+
ونتيجة لذلك ، التابع <code>[[Ruby/Marshal/load|load]]::</code> ليس مناسبًا ليكون كتنسيق تسلسل عام، ويجب ألا يتم تبديد  (unmarshal) البيانات المُدخلة من قبل المستخدم أو غيرها من البيانات غير الموثوقة.
حسب التصميم ، يمكن تحميل loaderize تقريبا أي فئة تحميلها في عملية Ruby. في العديد من الحالات ، يمكن أن يؤدي ذلك إلى تنفيذ التعليمات البرمجية عن بُعد في حالة تحميل بيانات Marshal من مصدر غير موثوق به.
 
  
ونتيجة لذلك ، لا يكون حمل "::" مناسبًا كتنسيق التسلسل للأغراض العامة ويجب ألا يتم أبدًا تجاهل إدخال المستخدم الذي تم توفيره أو البيانات الأخرى غير الموثوق بها.
+
إذا كنت تريد فك تسلسل (deserialize) البيانات غير الموثوقة، فاستخدم JSON أو تنسيق تسلسل آخر، والذي لا يمكنه أن يحمّل إلا الأنواع "البدائية" البسيطة مثل السلاسل النصية والمصفوفات والقواميس وما إلى ذلك. لا تسمح أبدًا لمدخلات المستخدم أن تحدد أنواع عشوائية لفك التسلسل.
  
إذا كنت بحاجة إلى إلغاء تسلسل البيانات غير الموثوقة ، فاستخدم JSON أو تنسيقًا آخر للتسلسل يمكنه فقط تحميل أنواع "بدائية" بسيطة مثل String و Array و Hash وما إلى ذلك. لا تسمح أبدًا لمدخلات المستخدم بتحديد أنواع تعسفية لإلغاء التسلسل.
+
== marshal_dump و marshal_load ==
 +
عند تفريغ (dumping) كائن سيتم استدعاء التابع <code>marshal_dump</code>. يجب أن يعيد التابع <code>marshal_dump</code> نتيجة تحتوي على المعلومات الضرورية لـ <code>marshal_load</code> لإعادة إنشاء الكائن. النتيجة يمكن  أن تكون أي كائن.
  
marshal_dump و marshal_load¶ ↑
+
عند تحميل كائن تم تفريغه باستخدام <code>marshal_dump</code>، يتم أولاً تحديد الكائن، ثم يُستدعى <code>marshal_load</code> وتُمرّر إليه النتيجة المُعادة من <code>marshal_dump</code>. يجب أن يعيد التابع <code>marshal_load</code> إنشاء الكائن انطلاقًا من المعلومات المُتضمنة في النتيجة.
  
عند تفريغ كائن سيتم استدعاء الأسلوب marshal_dump. يجب أن يقوم marshal_dump بإرجاع نتيجة تحتوي على المعلومات الضرورية لـ marshal_load لإعادة تكوين الكائن. يمكن أن تكون النتيجة أي كائن.
+
مثال:<syntaxhighlight lang="ruby">
 +
class MyObj
 +
  def initialize name, version, data
 +
    @name    = name
 +
    @version = version
 +
    @data    = data
 +
  end
  
عند تحميل كائن تم تفريغه باستخدام marshal_dump يتم أولاً تخصيص الكائن ثم يتم استدعاء marshal_load مع النتيجة من marshal_dump. يجب على marshal_load إعادة إنشاء الكائن من المعلومات الموجودة في النتيجة.<syntaxhighlight lang="ruby">
+
  def marshal_dump
LocalJumpError: no block given (yield)
+
    [@name, @version]
 +
  end
 +
 
 +
  def marshal_load array
 +
    @name, @version = array
 +
  end
 +
end
  
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
== ‎_dump و ‎_load ==
 +
استخدم التابعين ‎ <code>_dump</code> و <code>‎_load</code> عندما تريد تحديد الكائن الذي تود استعادته بنفسك.
 +
 +
عند تفريغ كائن، يُستدعى التابع ‎<code>_dump</code> مع تمرير عدد صحيح إليه إشارة إلى العمق الأقصى للكائنات التى ستُفرّغ (القيمة ‎ <code>-‎‎1</code>تعني أنه تعطيل التحقق من العمق). يجب أن يعيد التابع  ‎ <code>_dump</code> سلسلة نصية تحتوي على المعلومات الضرورية لإعادة إنشاء الكائن.
 +
 +
يأخذ الصنف <code>method_load</code> سلسلة نصية ويستخدمها لإعادة كائن من نفس الصنف.
 +
 +
مثال:<syntaxhighlight lang="ruby">
 +
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
 +
</syntaxhighlight>لما كان التابع <code>[[Ruby/Marshal/dump|dump]]</code> يعيد سلسلة نصية، يمكنك جعل <code>have_dump</code>  تعيد سلسلة Marshal ‎‏ (Marshal string)،
  
 
==توابع الصنف العامة (Public Class Methods)==
 
==توابع الصنف العامة (Public Class Methods)==
===[[Ruby/Marshal/dump | التابع ::dump]]===
+
===[[Ruby/Marshal/dump| التابع ::dump]]===
 
يُسلسل (Serializes) ظظظ الوسيط المعطى obj ططط وجميع الكائنات المنحدرة (descendant objects). في حال تمرير كائن IO، فستُكتب البيانات المُسَلسلة فيه، وإلا فستُعاد البيانات كسلسلة نصية (<code>String</code>). في حال تمرير limit، فسيقتصر عمل ظظظ على الكائنات الفرعية على العمق المحدد به. إذا كان limit سالباً، لن يتم إجراء أي تحقق للعمق.
 
يُسلسل (Serializes) ظظظ الوسيط المعطى obj ططط وجميع الكائنات المنحدرة (descendant objects). في حال تمرير كائن IO، فستُكتب البيانات المُسَلسلة فيه، وإلا فستُعاد البيانات كسلسلة نصية (<code>String</code>). في حال تمرير limit، فسيقتصر عمل ظظظ على الكائنات الفرعية على العمق المحدد به. إذا كان limit سالباً، لن يتم إجراء أي تحقق للعمق.
===[[Ruby/Marshal/load | التابع ::load]]===
+
===[[Ruby/Marshal/load| التابع ::load]]===
 
يعيد ظظظ نتيجة تحويل البيانات المُسلسلة (serialized) في المصدر إلى كائن في روبي (ربما مع كائنات ثانوية [subordinate objects] مرتبطة به). قد يكون المصدر إما نسخة من <code>IO</code>، أو كائنًا يستجيب إلى to_str. في حال تمرير الوسيط proc، فسيتم تمرير كل الكائنات إلى proc، أثناء فك تسلسلها (deserialisation).
 
يعيد ظظظ نتيجة تحويل البيانات المُسلسلة (serialized) في المصدر إلى كائن في روبي (ربما مع كائنات ثانوية [subordinate objects] مرتبطة به). قد يكون المصدر إما نسخة من <code>IO</code>، أو كائنًا يستجيب إلى to_str. في حال تمرير الوسيط proc، فسيتم تمرير كل الكائنات إلى proc، أثناء فك تسلسلها (deserialisation).
===[[Ruby/Marshal/restore | التابع ::restore]]===
+
===[[Ruby/Marshal/restore| التابع ::restore]]===
 
يعيد ظظظ نتيجة تحويل البيانات المُسلسلة (serialized) في المصدر إلى كائن في روبي (ربما مع كائنات ثانوية [subordinate objects] مرتبطة به). قد يكون المصدر إما كائنًا من الصنف <code>IO</code> أو كائنًا يستجيب إلى to_str. في حال تمرير الوسيط proc ، فسيتم تمرير كل الكائنات إلى proc، أثناء فك تسلسلها (deserialisation).
 
يعيد ظظظ نتيجة تحويل البيانات المُسلسلة (serialized) في المصدر إلى كائن في روبي (ربما مع كائنات ثانوية [subordinate objects] مرتبطة به). قد يكون المصدر إما كائنًا من الصنف <code>IO</code> أو كائنًا يستجيب إلى to_str. في حال تمرير الوسيط proc ، فسيتم تمرير كل الكائنات إلى proc، أثناء فك تسلسلها (deserialisation).
 
 
==مصادر<span> </span>==
 
==مصادر<span> </span>==
*[http://ruby-doc.org/core-2.5.1/LocalJumpError.html قسم  الصنف Marshal في توثيق روبي الرسمي.]
+
*[http://ruby-doc.org/core-2.5.1/LocalJumpError.html قسم  الصنف Marshal في توثيق روبي الرسمي.]<noinclude>{{DISPLAYTITLE: صفحة الصنف <code>Marshal</code> في روبي}}</noinclude>
<noinclude>{{DISPLAYTITLE: صفحة الصنف <code>Marshal</code> في روبي}}</noinclude>
 
 
[[تصنيف: Ruby]]
 
[[تصنيف: Ruby]]
 
[[تصنيف: Marshal]]
 
[[تصنيف: Marshal]]

مراجعة 17:47، 24 أكتوبر 2018

تحوّل المكتبة 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 من مصدر غير موثوق به.

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

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

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 ‎‏ (Marshal string)،

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

التابع ::dump

يُسلسل (Serializes) ظظظ الوسيط المعطى obj ططط وجميع الكائنات المنحدرة (descendant objects). في حال تمرير كائن IO، فستُكتب البيانات المُسَلسلة فيه، وإلا فستُعاد البيانات كسلسلة نصية (String). في حال تمرير limit، فسيقتصر عمل ظظظ على الكائنات الفرعية على العمق المحدد به. إذا كان limit سالباً، لن يتم إجراء أي تحقق للعمق.

التابع ::load

يعيد ظظظ نتيجة تحويل البيانات المُسلسلة (serialized) في المصدر إلى كائن في روبي (ربما مع كائنات ثانوية [subordinate objects] مرتبطة به). قد يكون المصدر إما نسخة من IO، أو كائنًا يستجيب إلى to_str. في حال تمرير الوسيط proc، فسيتم تمرير كل الكائنات إلى proc، أثناء فك تسلسلها (deserialisation).

التابع ::restore

يعيد ظظظ نتيجة تحويل البيانات المُسلسلة (serialized) في المصدر إلى كائن في روبي (ربما مع كائنات ثانوية [subordinate objects] مرتبطة به). قد يكون المصدر إما كائنًا من الصنف IO أو كائنًا يستجيب إلى to_str. في حال تمرير الوسيط proc ، فسيتم تمرير كل الكائنات إلى proc، أثناء فك تسلسلها (deserialisation).

مصادر