التطوير / ROBLOX
النطاق المحلي في Luau: أي اسم للمسار يقرأه الكود؟
تتبّع المتغيرات المحلية بين الكتل، وميّز التصريح باسم جديد عن تغيير قيمة موجودة، ثم اختبر مثال أسماء المسارات قبل استعمال الفكرة في Roblox.
ابدأ بسؤال عن إمكانية الوصول #
تخيّل مسار مشي افتراضياً يحمل الاسم العام Harbor، بينما يستخدم فرع اختياري الاسم المؤقت Tower. المطلوب معرفة الاسم المتاح لسطر محدد من البرنامج. النطاق يصف جزء الكود الذي يمكن فيه الوصول إلى متغير معلن، ولا يصف المسافة بين عناصر العالم أو مدة بقاء اللاعب على المسار. الفصل بين حدود الكود ومكان اللاعب يمنع تفسير المشكلة بطريقة خاطئة.
اقرأ المثال أولاً بوصفه Luau عادياً. دوّن كل تصريح والكتلة التي ينتمي إليها، ثم تتبّع أوامر print حسب ترتيب التنفيذ. هذه التدريبات تتعامل فقط مع سلاسل نصية في الذاكرة. لا تغيّر اسم مكان Roblox أو نقطة حفظ اللاعب أو لوحة داخل Workspace، ولا تحفظ بيانات المسار. تلك العمليات تحتاج إلى كود منفصل واختبارات مستقلة، ولا يمكن إثباتها بمجرد ظهور اسم في المخرجات.
تتبّع local داخل كتلة متداخلة #
يصرّح المثال الأول بالمتغير routeName قبل كتلة do. يستطيع print داخلها قراءة المتغير الخارجي، لأن الكتلة الداخلية تصل إلى الأسماء المعلنة في النطاق المحيط بها. ويظهر داخلها متغير محلي جديد اسمه branchName. الاسمان يشيران إلى متغيرين مختلفين، لذلك طباعتهما معاً لا تستبدل الاسم العام للمسار. وبعد انتهاء الكتلة يظل أمر الطباعة الأخير يقرأ Harbor.
توقّع النتيجة قبل التشغيل: Harbor وTower في السطر الأول، ثم Harbor في السطر التالي. يفصل بين وسيطي print الأول محرف جدولة. لاحظ أن branchName المحلي غير متاح خارج كتلته. إذا احتاج كود لاحق نتيجة محسوبة داخلها، فصمّم قيمة معادة أو متغيراً مستقبلاً مناسباً في الخارج. حذف local وحده ليس تصميماً واضحاً لنقل البيانات ولا يوضح الجهة التي تستخدم النتيجة.
local routeName = "Harbor"
do
local branchName = "Tower"
print(routeName, branchName)
end
print(routeName)الكتلة الخارجية لا تحصل على local الداخلية #
تنتقل إمكانية الوصول من النطاق المحيط إلى النطاق المتداخل، لكنها لا تعود تلقائياً إلى الخارج. ارسم إطاراً حول كتلة do: ينتمي branchName إلى داخل هذا الإطار. السطر اللاحق خارج الإطار لا يصل إلى التصريح المحلي نفسه. وإذا صرّحت بمتغير آخر باسم branchName في موضع مختلف، فهو متغير جديد، وليس وسيلة لاستعادة المتغير الأصلي.
عند ظهور nil غير متوقع، افحص موضع التصريح قبل تغيير الاسم في جميع الأسطر. في مثال مستقل عادي، قد يرجع المعرّف غير المرتبط بتصريح ظاهر إلى قيمة عامة غير موجودة ويعطي nil. ذلك لا يكشف المتغير المحلي الداخلي. وقد يشير تحليل Studio أيضاً إلى أسماء غير معروفة. تعامل مع الملاحظة كمشكلة حدود في الكود، لا كدليل على حذف النص المتوقع من بيانات محفوظة.
افصل التصريح عن الإسناد #
يكتب المثال الثاني local routeName داخل كتلة فرعية. هذا تصريح جديد يحجب routeName الخارجية: الكتابة نفسها تشير داخلياً إلى متغير آخر قيمته Tower. عندما تنتهي الكتلة يصبح المتغير الخارجي ظاهراً من جديد وما زال يحمل Harbor. قد يكون حجب الاسم مقصوداً، لكنه قد يحدث بالخطأ حين يريد المبتدئ تحديث القيمة الخارجية ويضيف local دون الانتباه إلى أثرها.
تستخدم الكتلة التالية routeName = "Market" من دون تصريح local جديد. المتغير الظاهر في هذا الموضع هو routeName المحلي الخارجي، ولذلك يغيّر الإسناد قيمته. تصبح المخرجات الأخيرة Market. قارن الأسطر الثلاثة: Tower ثم Harbor ثم Market. الفرق الأساسي هو التصريح، وليس علامتي الاقتباس أو do نفسها. استخدم أسماء مختلفة وواضحة عندما تمثل القيم مفاهيم مختلفة في تصميم المسار.
local routeName = "Harbor"
do
local routeName = "Tower"
print(routeName)
end
print(routeName)
do
routeName = "Market"
end
print(routeName)انتبه إلى موضع التصريح #
يتاح المتغير المحلي بعد تصريحه ضمن النطاق المناسب. لا تفترض أن local المكتوبة لاحقاً تفسر كل استعمال سابق للاسم نفسه. اقرأ الكتلة من الأعلى إلى الأسفل وحدّد التصريح الظاهر عند كل استعمال. يفيد ذلك خصوصاً داخل دالة تحتوي على كتل قصيرة متعددة واسم متكرر؛ تتبّع كل سطر أدق من التخمين اعتماداً على الاسم وحده.
كتدريب، اكتب بجانب كل print المتغير الذي يفترض أن يقرأه. اترك الأمثلة التنفيذية كما هي في التجربة الأولى، ثم غيّر شيئاً واحداً بصورة مقصودة. نقل التصريحات وإعادة التسمية وتغيير القيم في الوقت نفسه يصعّب معرفة سبب المخرجات الجديدة. سجّل توقعك منفصلاً عن النتيجة الفعلية، وارجع إلى التصريحات والحدود عندما لا يتطابقان، بدلاً من اعتماد نتيجة صحيحة بالصدفة.
للدوال حدود إضافية #
تنتمي معاملات الدالة ومتغيراتها المحلية إلى نطاق الدالة نفسها. لا يحصل الكود المستدعي على هذه الأسماء لمجرد استدعائها. إذا احتاج اسماً محسوباً، اجعل الدالة تعيده ثم أسند النتيجة إلى متغير محلي مسمى بوضوح عند الاستدعاء. تستطيع دالة متداخلة استعمال متغيرات خارجية محلية متاحة لها، لذلك قد يؤدي نقل الدالة إلى موضع آخر إلى تغيير القيم التي تستطيع الوصول إليها.
ميّز إمكانية الوصول عن نقل النتيجة. الدالة التي تطبع اسماً أنشأت مخرجات، لكنها لم تُعد بالضرورة قيمة إلى المستدعي. وحتى إعادة سلسلة نصية لا تحدّث واجهة Roblox تلقائياً. افحص كل حد على حدة: ما المدخلات المتاحة، وما النتيجة التي تعاد عبر return، وأي جزء من الكود المستدعي سيطبق النتيجة على العنصر المطلوب بعد ذلك.
العام لا يعني جميع سكربتات Roblox #
الإسناد إلى اسم لا يقابله متغير محلي ظاهر قد ينشئ أو يغيّر متغيراً عاماً في بيئة التنفيذ الحالية. يوسّع ذلك الوصول داخل تلك البيئة ويجعل تضارب الأسماء العرضي أصعب في التتبّع. لكنه لا ينشئ متغيراً مشتركاً موثوقاً بين سكربتات Roblox المنفصلة والعملاء والخادم. النطاق ليس آلية اتصال شبكي ولا طريقة لحفظ تقدم اللاعب بين الجلسات.
ابدأ بمتغيرات محلية صريحة. لمشاركة تعريفات بين سكربتات، ادرس واجهة وحدة مصممة بوضوح؛ وللاتصال بين العميل والخادم، ادرس الآلية المناسبة والتحقق من البيانات. هذه مهام مختلفة عن التمرين الحالي. استبدال local غير المتاحة باسم عام لا يثبت إصلاح مزامنة اللعب الجماعي أو التحقق من الصلاحيات أو التخزين الدائم لحالة اللاعب، فلكل منها اختباره الخاص.
| التحقق | النتيجة المتوقعة |
|---|---|
| قراءة الخارجي في الداخل | يمكن الوصول إلى Harbor |
| قراءة الداخلي في الخارج | local الداخلية غير متاحة |
| حجب routeName | يبقى الخارج Harbor |
| الإسناد إلى routeName الخارجية | يصبح الخارج Market |
جهّز تسليماً قابلاً للتحقق #
يتضمن التسليم المفيد المثال غير المعدّل، والمخرجات المتوقعة، ونتيجة تشغيل حقيقية. علّم التصريح الداخلي بوصفه متغيراً جديداً، والإسناد اللاحق بوصفه تحديثاً للمتغير الخارجي الظاهر. أضف تحققاً سلبياً يوضح أن الاسم المحصور في الكتلة الداخلية غير متاح خارجها. تؤكد اختباراتنا المستقلة هذه الحدود من دون تعديل ألعاب Roblox الموجودة أو الادعاء بإجراء اختبار جماعي داخل Studio.
قبل تطبيق النمط على سكربت فعلي، حدّد المتغير المقصود وجميع الكتل التي تستخدمه. اشرح هل ينبغي أن يبقى التغيير مؤقتاً، أو يحدّث قيمة خارجية، أو يغادر الدالة كقيمة معادة. نفّذ اختباراً مناسباً في نسخة تطوير منفصلة وسجّل ما شاهدته. نجاح المثال النصي يثبت سلوكه المحلي فقط، ولا يثبت صحة نظام المسارات أو الواجهة أو حفظ البيانات في اللعبة كاملة.
| حقل التسجيل | ما ينبغي تضمينه |
|---|---|
| المتغير | routeName |
| الكتلة | التصريح والاستعمال الدقيقان |
| التوقع | القيمة المتوقعة من print |
| الملاحظة | المخرجات الفعلية للتشغيل |