التطوير / ROBLOX
إعدادات false في Luau: لماذا أعادت القيمة الافتراضية تشغيل الموسيقى؟
حافظ على اختيار false المقصود في تمرين أصلي لإعداد الموسيقى، واستخدم القيمة الافتراضية عند غياب البيانات فقط. ميّز بين القيمة المفقودة والمدخل غير الصحيح والاختيار الصحيح للإيقاف قبل توصيل القائمة أو التخزين.
حدّد معنى كل قيمة أولاً #
تخيّل لعبة خيالية للمشي في جزيرة، لها إعداد مستقل للموسيقى الخلفية. يوقف اللاعب الموسيقى، فتحتوي بيانات التمرين على false. أما اللاعب الجديد فلم يختر بعد، ولذلك يكون المدخل nil. يريد المصمم تشغيل الموسيقى افتراضياً في الحالة الثانية فقط. هذا الاتفاق يفصل القرار المقصود عن المعلومات المفقودة قبل أن يخلط تعبير مختصر بين الحالتين.
لا يعني التمرين أن هذا الإعداد موجود بالفعل في ألعابنا. نبدأ بدالة Luau عادية وقيم بسيطة، دون Sound أو طلب DataStore أو زر أو حدث شبكي. تتطلب هذه الأجزاء تنفيذاً منفصلاً واختبارات لاحقة في Studio. اكتب أولاً أن true يعني التشغيل، وfalse يعني الإيقاف، وnil يعني عدم تقديم قيمة. هذا اتفاق تصميم واضح، وليس تفسيراً تلقائياً لكل مدخل ممكن.
أعد إنتاج خطأ القيمة البديلة باستخدام or #
يبدو التعبير savedMusic or true طريقة مريحة لاختيار قيمة افتراضية. لكن or لا يتحقق حصراً من غياب المعلومات. يوضح المرجع الرسمي أنه يعيد المعامل الأول إذا اعتُبر صحيحاً، وإلا يعيد الثاني. عندما تكون savedMusic مساوية لـfalse، تصبح النتيجة true. وهكذا يتحول اختيار الإيقاف الصريح إلى تشغيل أثناء تفسير البيانات بعد وصولها.
نفّذ مثالاً صغيراً بقيمة false واطبع النتيجة، ثم كرر مع true وnil. تبقى true كما هي، بينما تختار false وnil القيمة البديلة. هذا سلوك اللغة، وليس دليلاً على فشل تحميل البيانات. افحص التعبير قبل إعادة كتابة السجل: قد تصل بيانات صحيحة تماماً ثم تتحول إلى إعداد خاطئ بسبب طريقة تفسيرها بعد القراءة.
local savedMusic = false
print(savedMusic or true)
print(0 or 9)
print(true and false or true)لا تعتبر الصفر والنص الفارغ اختياراً للإيقاف #
في Luau تُعتبر false وnil قيمتين زائفتين في هذا التقييم، بينما يُعتبر الصفر والنص الفارغ صحيحين. لذلك يعيد 0 or 9 الصفر، وتبقى السلسلة الفارغة فارغة عند جمعها مع نص بديل بواسطة or. لن تحصل تسمية فارغة بالضرورة على الرسالة التي توقعتها. افحص القيمة الفعلية قبل أن تنسب المشكلة إلى عرض الواجهة.
مع ذلك، لا يمثل الصفر إعداد إيقاف صالحاً في اتفاقنا. نقبل قيماً منطقية فقط، لا كل قيمة لها سلوك معين في الشروط. والنص "false" ليس القيمة المنطقية false. أضف هذه المدخلات إلى قائمة الحالات غير الصحيحة. اجتياز شرط if لا يثبت صحة النوع، ولا يثبت أن المدخل يمثل اختياراً مؤكداً ومسموحاً للاعب.
استبدل nil فقط بفحص صريح #
تبدأ الدالة booleanPreference بفحص raw==nil. هذا الفرع وحده يعيد defaultValue المتفق عليها. إذا كانت هناك قيمة، تفحص الدالة بصورة منفصلة type(raw)=="boolean". تمرّ true وfalse الحقيقيتان دون تغيير. ويُرفض الرقم أو النص بدلاً من استبداله بصمت. بذلك يبقى غياب البيانات متميزاً عن الإيقاف المقصود وعن المدخل ذي الصيغة غير الصحيحة.
يجب أن تكون defaultValue نفسها منطقية في هذا التمرين. يشير assert إلى خطأ برمجي في استدعاء الدالة، وليس سياسة كاملة لمعالجة أي مدخل في واجهة جاهزة. حدّد مصدر القيمة الافتراضية المسموح بها وما تفعله الواجهة عند الرفض. لا ينبغي أن يتحول نص لاعب غير مفحوص فجأة إلى القيمة الافتراضية لإعداد المنتج.
local function booleanPreference(raw, defaultValue)
assert(type(defaultValue) == "boolean")
if raw == nil then
return defaultValue, true
end
if type(raw) ~= "boolean" then
return nil, false
end
return raw, true
end
local value, valid = booleanPreference(false, true)
print(value, valid)
value, valid = booleanPreference(nil, false)
print(value, valid)
value, valid = booleanPreference("false", true)
print(value, valid)افصل قيمة النتيجة عن نجاح التحقق #
تعيد الدالة نتيجتين: التفضيل وvalid. الاختيار الصحيح للإيقاف هو false,true، بينما الرفض هو nil,false. إذا فحص المستدعي النتيجة الأولى فقط، فقد يدخل اختيار إيقاف صحيح في فرع الخطأ نفسه. افحص valid أولاً ثم طبّق value. نجاح العملية وماهية القيمة التي أنتجتها بنجاح سؤالان مختلفان، حتى لو كانت القيمة الصحيحة false.
قد يحصل معالج زر مستقبلي على false,true فيعرض حالة الإيقاف. أما nil,false فتحتاج مسار خطأ مخططاً له، لا تشغيل الصوت تلقائياً. لا يختار المقال سياسة منتج كاملة نيابة عنك. قد يناسب تصميمك الاحتفاظ بالحالة المؤكدة السابقة وإظهار المشكلة. القاعدة الأساسية هي ألا تقدّم رفض البيانات باعتباره اختياراً جديداً أجراه اللاعب.
راجع اختصار and/or #
يُستخدم أحياناً التعبير condition and selectedValue or fallback كاختيار مختصر. لكنه لا يحافظ على كل selectedValue مسموح بها. عندما تكون condition مساوية لـtrue وselectedValue مساوية لـfalse، تكون النتيجة الوسيطة false، فيختار or القيمة البديلة. لذلك يعطي true and false or true النتيجة true مرة أخرى. صدق الشرط لا يحمي نتيجة زائفة في هذا الاختصار.
استخدم فرعاً صريحاً إذا كانت النتيجة المختارة قد تكون false أو nil. قِصر التعبير ليس اختبار صحة. احتفظ بحالة اختبار يكون فيها الشرط صحيحاً والقيمة المختارة false؛ أمثلة true وحدها لن تكشف الخطأ. يشرح دليل العتبات الموجود اختيار أول فرع عددي مناسب، بينما يحافظ هذا التمرين المختلف على نتيجة صحيحة تعتبرها اللغة زائفة.
نفّذ مصفوفة المدخلات #
اختبر الحالات الصحيحة منفصلة: false مع defaultValue=true يجب أن تعيد false,true. وtrue مع defaultValue=false يجب أن تعيد true,true. أما nil مع defaultValue=true فتعيد true,true. أضف nil مع defaultValue=false كحالة معاكسة للمعلومات المفقودة. دوّن التوقعات قبل التنفيذ حتى لا يصبح التشغيل العرضي نتيجة مقبولة فقط لأن البرنامج أنتجها.
بعد ذلك مرّر الصفر والنص الفارغ والنص "false" والرقم واحد. يجب أن تعيد جميعها nil,false وفق اتفاقنا. افحص النتيجتين، لا مجرد عدم انهيار التنفيذ. نُفذت مجموعة assertions الأصلية فعلياً في مفسر Luau مستقل. تؤكد عمليات البيانات المذكورة، لكنها لا تؤكد سماع الموسيقى أو ضغط الأزرار أو حفظ تفضيل اللاعب داخل Roblox.
| المدخل | النتيجة |
|---|---|
| false | false, true |
| true | true, true |
| nil | defaultValue, true |
| 0 / "false" | nil, false |
صِل القائمة في مرحلة منفصلة #
بعد نجاح الدالة، حدّد مصدر المدخل ووقت اكتمال القراءة والحالة المؤكدة التي تستقبلها القائمة. ينبغي أن تحافظ إعادة فتح اللوحة على اختيار الإيقاف. وعند غياب البيانات تُطبّق القيمة المتفق عليها في السيناريو المقصود. لا ينبغي أن تعيد عملية رسم الواجهة تفسير false كغياب لمجرد أن اللوحة نفسها ظهرت مرة أخرى.
لا توسّع نجاح اختبار بيانات بسيط إلى ادعاء أن DataStore أو الخادم يعملان بصورة صحيحة. قد يحتاج فشل التحميل وغياب السجل ورفض النوع إلى إجراءات مختلفة. تبقى فحوص الخادم ومعالجة الأخطاء الموثوقة مهمتين مستقلتين. لا تستبدل سجل اللاعب بقيمة بديلة لأن اللوحة ظهرت قبل انتهاء القراءة. حدّد هذه الحالات الزمنية قبل تنفيذ الحفظ.
اترك تسليماً قابلاً لإعادة التنفيذ #
اكتب الأنواع المسموح بها ومعنى nil والنتيجتين وحالات الرفض. أرفق ملفات المصدر ونتيجة الفحص الفعلية. هذا أنفع من القول إن الموسيقى أُصلحت، لأن مطوراً آخر يستطيع تكرار اختبار البيانات دون الوصول إلى جلسة لعبك. استخدم مدخلات خيالية واترك معرّفات اللاعبين الحقيقية وبيانات الدخول خارج الأمثلة التعليمية.
إذا تغير الاتفاق لاحقاً، حدّث الدالة والتوقعات والشرح معاً. دعم وضع إضافي ممثّل بنص يتطلب تفسيراً صريحاً واختبارات جديدة، لا مجرد حذف فحص النوع. حافظ على الفرق بين قرار المنتج وسلوك اللغة. يشرح المرجع الرسمي دلالة العمليات، بينما يحدد مشروعك قيم التفضيلات التي تحمل معنى وتُعتبر مسموحاً بها.
افحص النتيجة قبل تسليمها #
ينجح التمرين عندما تبقى false المحفوظة false، وتحصل nil على القيمة الافتراضية المتفق عليها فقط، وتؤدي الأنواع غير الصحيحة إلى رفض مستقل. اختبر القيمتين الافتراضيتين الممكنتين والاستدعاءات المتكررة. تأكد من أن الكود المستدعي يعتمد على valid ليقرر تطبيق النتيجة. ابحث عن اختصار and/or حيث يمكن أن تكون false نتيجة صحيحة.
بعد التكامل كرّر الاختبارات على اللوحة الحقيقية في Studio، واختبر الحفظ وإعادة القراءة بصورة مستقلة. هذه خطوات تحقق مستقبلية، وليست مشاهدات لعب مكتملة. يوضح المثال الأصلي ومصدره الرسمي سبب الخطأ، لكنهما لا يعنيان تعديل لعبة موجودة بالفعل. دوّن نتيجة الدالة المؤكدة ونتيجة اللعبة اللاحقة كل واحدة على حدة.
| الفحص | الإجراء |
|---|---|
| النوع | boolean |
| قيمة مفقودة | فرع nil منفصل |
| النتيجة | افصل value وvalid |
| التكامل | افحص في Studio |