Ruby / العقود: الاستدعاء والتقييم والإخفاق ونماذج القيم / الدرس 11
اختيار Data أو Struct بدلالات قيمة صريحة
افهم الأعضاء المولدة وكائنات القيمة السطحية ونسخ with وعقد eql?/hash ومفاتيح المجموعات المستقرة.
في هذه الصفحة
أهداف الدرس
- ميّز قيود إسناد Data من الثبات العميق والتحقق.
- أبعد الحالة القابلة للتعديل عن حقول مفاتيح التجزئة المحددة للمساواة.
اختر سلوك السجل الذي يحتاجه التطبيق
تنشئ Struct صنفاً بطرائق لقراءة الأعضاء وإسناد قيمها، وعمليات متعددة تعتمد على القيمة. وتعرّف Data، التي ظهرت في Ruby 3.2 ضمن مرجع 3.3، أصنافاً شبيهة بالقيم من دون طرائق عادية لإسناد قيم الأعضاء. ليست أيهما مخطط مجال كاملا أو حدا للتفويض. قد تسمح Struct بتحويل أعضاء مغفلة إلى nil حسب البناء، ولـ Data قواعدها للمطلوب. اقرأ الإنشاء ولا تفترض التبادل. اختر صنفا عاديا عندما تتمحور الفكرة حول تحقق أغنى أو انتقالات مضبوطة.
أنشئ قيمة مختلفة بدلا من إسناد عضو
يحفظ مثال Data عدد الأصل، وتنشئ with سجلا ثانيا بعدد مختلف. تقارن المساواة سجلات متوافقة وفق أعضائها لا الهوية وحدها. لا يتحقق النموذج من الإيجابية أو الصيغة أو الملكية؛ فلها حد بناء مقصود. تحتاج Data تنفيذا يوفرها، فلا تدعي الدورة توافقا مع Ruby أقدم. لم يوجد تنفيذي Ruby ولم يُقَس المخرج أو يُرصد.
RecordValue = Data.define(:id, :copies)
first = RecordValue.new(id: 'A-5', copies: 1)
changed = first.with(copies: 2)
puts first.copies
puts changed.copies
puts(first == RecordValue.new(id: 'A-5', copies: 1))
1
2
true
المخرج المتوقع 1 ثم 2 ثم true. لا يعاد إسناد عضو الأصل. تتطلب Data نسخة 3.2 أو أحدث؛ ويتبع المصدر وثائق 3.3 المختارة ولم يُنفذ.
قد يحمل غلاف قيمي مراجع قابلة للتعديل
لا تجمد Data الأعضاء تكراريا. قد تبقى المصفوفة أو النص مشتركة وتتغير رغم غياب الكاتب. وتتبع with مراجع الأعضاء ما لم تستبدلها. حدّد هل يعد النموذج بقيمة عميقة ثابتة أو سجل سطحي أو بيانات حية مشتركة. قد تضعف الأعضاء المعدلة المفاتيح واللقطات وافتراضات المساواة. قد تناسب عناصر ثابتة أو سياسة نسخ؛ ولا يصح نسخ عميق عام تلقائيا للموارد والدورات والهويات المشتركة المقصودة.
افحص الداخل ولا تثق باسم الصنف
يعدل المثال مصفوفة معطاة بعد بناء Data. يظهر التغيير عبر طريقة قراءة العضو، وتؤكد respond_to? غياب labels= العادية. يجيب ذلك سؤالين مختلفين ولا يعني أن Data معيبة. استخدم قيما داخلية اصطناعية لفحص الملكية الموعودة معزولا. لا يحول تجميد الغلاف أو تسميته Snapshot العناصر المعدلة إلى ثابتة، ولا تثبت مساواة ناجحة وحدها العزل.
Labelled = Data.define(:labels)
labels = ['raw']
record = Labelled.new(labels: labels)
labels << 'extra'
puts record.labels.join('|')
puts record.respond_to?(:labels=)
raw|extra
false
المخرج المتوقع raw|extra ثم false. يختلف إسناد العضو عن تعديل كائنه. لم يُنفذ السكربت.
تحتاج مفاتيح Hash ثبات eql? و hash
تستخدم Hash عادة hash و eql? لهوية المفتاح، وهو عقد يختلف عن كل استعمال لـ==. يجب اتساقهما في المفتاح المخصص وثبات حالة المساواة أثناء التخزين. لا تثبت التجزئات المتطابقة المساواة لوجود التصادم. لا تحفظ hash معرفا دائما أو تفويضا. افحص سجلات مستقلة متساوية وأخرى مختلفة وتعديل الداخل والبحث في التنفيذ المختار عند توفره. لا تثبت الدورة نتائج مساواة أو تجزئة أو تزامن منفذة.
الأخطاء الشائعة وإصلاحها
تتغير مصفوفة عضو Data على غير المتوقع.
- لماذا يحدث؟
- احتفظ غلاف القيمة بمرجع مشترك قابل للتعديل.
- كيف تصلحه؟
- اختر أعضاء ثابتة أو سياسة نسخ وملكية محددة.
- كيف تتجنب تكراره؟
- اختبر تعديل المصدر والداخل بعد البناء.
تتجاوز طريقة إسناد مولدة في Struct القيد المطلوب.
- لماذا يحدث؟
- قُبل التعديل المولد دون عقد نموذج.
- كيف تصلحه؟
- استخدم طرقا مضبوطة أو نموذجا قيميا ببناء متحقق.
- كيف تتجنب تكراره؟
- راجع طرائق قراءة الأعضاء وإسنادها التي يولدها الصنف باعتبارها جزءاً من الواجهة العامة.
يصبح مفتاح تجزئة غير موثوق بعد تعديل حقل.
- لماذا يحدث؟
- تغير عقد hash/eql? أثناء التخزين.
- كيف تصلحه؟
- استخدم حقول قيمة ثابتة أو إزالة وإدراجا مقصودين.
- كيف تتجنب تكراره؟
- راجع المساواة والتعديل معا قبل استخدام المفتاح.
اختبر فهمك
1. هل تنشئ with نسخة عميقة لسجل Data؟
اعرض الحل المشروح
لا. تحتفظ الأعضاء غير المستبدلة بمراجعها فتشترك الكائنات المعدلة الداخلية. حدّد مستويات الاستقلال ومعنى الهوية، وانسخ أو استبدل وفق العقد. لا تفترض أن الواجهة القيمية تجمد تكراريا، وتحقق من المحتوى الناتج مستقلا.
2. لماذا لا يكفي تجاوز == وحدها لمفتاح Hash مخصص؟
اعرض الحل المشروح
يدخل eql? و hash في عقد المفاتيح، وقد يتركهما تجاوز == بسلوك هوية أو غير متسق. عرّف التكافؤ والتجزئة معا وثبّت الحالة وافحص البحث بمثيلات مستقلة متساوية. لا علاقة لجمال العرض بذلك المطلب.
أهم ما تعلمته
- لا تستبدل عمليات القيمة المولدة تحقق المجال أو الملكية العميقة.
- تتطلب المفاتيح الثابتة مساواة وتجزئة متسقتين لحالة مستقرة.