كيفية عمل نسخ عميقة في روبي

click fraud protection

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

كائنات ومراجع

لفهم ما يحدث ، دعنا نلقي نظرة على بعض الرموز البسيطة. أولاً ، يقوم عامل التخصيص باستخدام نوع POD (البيانات القديمة البسيطة) في روبي.

أ = 1
ب = أ
أ + = 1
يضع ب

هنا ، يقوم عامل التخصيص بعمل نسخة من قيمة أ وإسنادها إليه ب باستخدام عامل التعيين. أي تغييرات على أ لن ينعكس في ب. ولكن ماذا عن شيء أكثر تعقيدًا؟ فكر في هذا.

أ = [1،2]
ب = أ
أ << 3
يضع ب

قبل تشغيل البرنامج أعلاه ، حاول تخمين ماذا سيكون الناتج ولماذا. هذا ليس مثل المثال السابق ، التغييرات التي تم إجراؤها أ تنعكس في ب، لكن لماذا؟ هذا لأن مجموعة مصفوفة الكائن ليس من نوع POD. لا يقوم عامل التخصيص بعمل نسخة من القيمة ، بل يقوم ببساطة بنسخ مرجع إلى كائن الصفيف. ال أ و ب المتغيرات الآن المراجع إلى نفس الكائن Array ، سيتم رؤية أي تغييرات في أي من المتغيرين في الآخر.

والآن يمكنك أن ترى لماذا يمكن أن يكون نسخ الكائنات غير التافهة بمراجع لكائنات أخرى أمرًا صعبًا. إذا قمت ببساطة بعمل نسخة من الكائن ، فأنت تقوم فقط بنسخ المراجع إلى الكائنات الأعمق ، لذلك تتم الإشارة إلى نسختك باسم "نسخة ضحلة".

instagram viewer

ما يوفره روبي: خداع واستنساخ

يوفر روبي طريقتين لعمل نسخ من الأشياء ، بما في ذلك طريقة يمكن القيام بها لعمل نسخ عميقة. ال الكائن رقم مزدوج ستجعل الطريقة نسخة ضحلة من كائن. لتحقيق ذلك ، فإن مزدوج طريقة استدعاء تهيئة النسخ طريقة تلك الفئة. يعتمد ما يفعله هذا بالضبط على الفصل. في بعض الفئات ، مثل Array ، سيقوم بتهيئة مصفوفة جديدة بنفس أعضاء المصفوفة الأصلية. هذه ليست نسخة عميقة. خذ بعين الاعتبار ما يلي.

أ = [1،2]
ب = أ
أ << 3
يضع ب
أ = [[1،2]]
ب = أ
أ [0] << 3
يضع ب

ماذا حدث هنا؟ ال الصفيف # تهيئة_النسخ ستقوم الطريقة بالفعل بعمل نسخة من مصفوفة ، ولكن هذه النسخة نفسها هي نسخة ضحلة. إذا كان لديك أي أنواع أخرى غير POD في الصفيف الخاص بك ، فقم باستخدام مزدوج ستكون نسخة عميقة جزئيًا فقط. سيكون أعمق فقط مثل الصفيف الأول ، أي أعمق صفائف, تجزئات أو سيتم نسخ الأشياء الأخرى الضحلة فقط.

هناك طريقة أخرى جديرة بالذكر ، استنساخ. طريقة الاستنساخ تفعل نفس الشيء مزدوج مع تمييز واحد مهم: من المتوقع أن تتجاوز الأشياء هذه الطريقة بأخرى يمكنها عمل نسخ عميقة.

إذن عمليا ماذا يعني هذا؟ هذا يعني أن كل فئة من فئاتك يمكن أن تحدد طريقة استنساخ تقوم بعمل نسخة عميقة من هذا الكائن. هذا يعني أيضًا أنه يجب عليك كتابة طريقة استنساخ لكل فصل دراسي تقوم به.

خدعة: التنظيم

"تنظيم" كائن طريقة أخرى لقول "إجراء تسلسل" كائن. بمعنى آخر ، قم بتحويل هذا الكائن إلى دفق حرف يمكن كتابته إلى ملف يمكنك "إلغاء تنظيمه" أو "إلغاء تسلسله" لاحقًا للحصول على نفس الكائن. يمكن استغلال هذا للحصول على نسخة عميقة من أي كائن.

أ = [[1،2]]
ب = Marshal.load (Marshal.dump (a))
أ [0] << 3
يضع ب

ماذا حدث هنا؟ المارشال ينشئ "تفريغ" من الصفيف المتداخل المخزن في أ. هذا التفريغ عبارة عن سلسلة أحرف ثنائية مخصصة لتخزينها في ملف. يضم محتويات المصفوفة كاملة ، نسخة كاملة عميقة. التالى، المارشال يفعل العكس. يوزع هذا الصفيف من الأحرف الثنائية ويخلق صفيفًا جديدًا تمامًا ، مع عناصر صفيف جديدة تمامًا.

لكن هذه خدعة. إنه غير فعال ، لن يعمل على جميع الكائنات (ماذا يحدث إذا حاولت استنساخ اتصال شبكة بهذه الطريقة؟) وربما لا يكون سريعًا بشكل رهيب. ومع ذلك ، فهي أسهل طريقة لجعل النسخ العميقة أقل من المخصص تهيئة النسخ أو استنساخ طرق. أيضا ، نفس الشيء يمكن القيام به بأساليب مثل to_yaml أو to_xml إذا كان لديك مكتبات محملة لدعمها.

instagram story viewer