الإكمال السطري والمحادثة
درس 3 من 12
3الإكمال السطري والمحادثة
الوضعان الأكثر استخدامًا يوميًا، ومعهما تمرين حقيقي يكشف كيف يغيّر «تحسين» بريء سلوك الكود بلا أن يخبرك أحد.
ماذا تشاهد في الرسم: تكتب بداية الدالة، فيظهر بقية السطر رماديًا، وTab يقبله. القراءة قبل القبول هي العادة كلها.
خارطة هذا الجزء
المفاهيم بالترتيب، اضغط أيًّا منها للقفز إليه:
طريقان إلى نفس الفكرة
الإكمال السطري مثل صديق يكمل جملتك وأنت تتكلم: سريع ومريح، لكنه أحيانًا يقول ما لم تقصده. والمحادثة مثل أن تلتفت إليه وتسأله «اشرح لي هذا». الخطر أن تقبل «تحسينًا» يبدو بريئًا وهو في الحقيقة غيّر المعنى، ولا يكشفه إلا اختبار.
الإكمال السطري يقترح كودًا من السياق المحيط بالمؤشر وتقبله بـTab. والمحادثة تفهم وتشرح وتعيد الكتابة ضمن ملفات تختارها. التمرين يبيّن كيف تغيّر إعادة كتابة دالة متداخلة سلوكها في حالة حدّية، ولهذا تكتب اختبارًا يثبت السلوك قبل أن تقبل أي اقتراح.
المتطلبات قبل البداية
الجزء الثاني
محرر وإضافة تعملان. لو لم يظهر عندك نص رمادي ولا ردّت المحادثة، ارجع وأكمل الجزء السابق أولًا.
أساسيات جافاسكربت
تكفيك معرفة أن if شرط وأن return تُرجع قيمة. التمرين عن شكل الكود لا عن اللغة.
استعداد للاختبار
الدرس الأهم هنا لن تصل له إلا إذا شغّلت النسختين وقارنت. القراءة وحدها لا تكشفه.
المفاهيم الأساسية
هذان الوضعان هما ما ستستخدمه كل يوم. المهمة الثانية تجعلك تجرّبهما على كود واحد، وتحتها درس أعمق مما يبدو.
1الإكمال السطري: اقتراح صامت
تكتب، فيظهر نص رمادي باهت أمام المؤشر يكمل ما بدأته. تضغط Tab فيُقبل، أو تواصل الكتابة فيختفي. ليس فيه نقاش ولا تفسير، اقتراح صامت.
ما يجيده: الاستيرادات، هياكل الدوال، الحلقات المعتادة، الأسماء المتوقّعة. وما يخطئ فيه: أي شيء يعتمد على نيّتك أنت. النموذج يخمّن من النمط لا من الفهم.
2المحادثة: وضع الفهم
اللوحة الجانبية تختلف جوهريًا: هنا تسأل وتقرأ وتناقش. وهي ترى الملف المفتوح، فسؤالك «أعد كتابة هذه الدالة لتكون أسهل قراءة» له سياق.
والفرق العملي: الإكمال يكتب، والمحادثة تشرح. واستخدامك للمحادثة بسؤال «لماذا؟» بعد كل اقتراح هو ما يحوّل الأداة من مُنجِز إلى مُعلِّم.
3التمرين: الدالة المتداخلة
المشروع يعطيك هذه الدالة ويطلب منك أن تسأل المحادثة إعادة كتابتها «بلا تغيير ما تفعله». والعبارة الأخيرة هي بيت القصيد.
// snippet.js - a small function that needs cleanup
function checkUser(u) {
if (u.age > 18) {
if (u.subscribed == true) {
if (u.country != "FR") {
return true;
} else {
return false;
}
}
}
return false;
}مشاكلها ظاهرة: ثلاثة مستويات تداخل، وelse { return false; } زائدة، وu لا يشرح نفسه. والنموذج سيقترح شيئًا قريبًا من هذا:
// what the AI typically suggests: flat, readable, named
function isEligible(user) {
const isAdult = user.age > 18;
const hasSubscription = Boolean(user.subscribed);
const isOutsideFrance = user.country !== "FR";
return isAdult && hasSubscription && isOutsideFrance;
}أوضح بكثير: مسطّحة، والشروط لها أسماء، والمنطق في سطر واحد. لكن هل تفعل نفس الشي؟
4الاختبار الذي يكشف الفرق
على الحالات الطبيعية: نعم، متطابقة تمامًا.
$ node snippet.js
{"age":30,"subscribed":true,"country":"SA"} -> true | true same
{"age":30,"subscribed":true,"country":"FR"} -> false | false same
{"age":17,"subscribed":true,"country":"SA"} -> false | false same
{"age":30,"subscribed":false,"country":"SA"} -> false | false same
{"age":19,"subscribed":1,"country":"US"} -> true | true same
{"age":18,"subscribed":true,"country":"US"} -> false | false same
behaviour identical: trueوعلى حالات أغرب، وهي تحصل في بيانات حقيقية، لا:
$ node edge-cases.js
{"age":30,"subscribed":"yes","country":"SA"} checkUser: false | Boolean(): true DIFFERENT
{"age":30,"subscribed":2,"country":"SA"} checkUser: false | Boolean(): true DIFFERENT
{"age":30,"subscribed":"1","country":"SA"} checkUser: true | Boolean(): true same
"yes" == true -> false
2 == true -> false
Boolean("yes") -> true
Boolean(2) -> trueالسبب: x == true في جافاسكربت ليست «هل القيمة صادقة؟». إنها تحوّل الطرفين إلى أرقام، فـtrue تصير 1 و"yes" تصير NaN فلا يتساويان. بينما Boolean(x) تسأل «هل القيمة صادقة؟» فتقبل أي نص غير فارغ وأي رقم غير صفر.
5إعادة الكتابة الأمينة
لو كان المطلوب «بلا تغيير ما تفعله» حرفيًا، فالنسخة الصحيحة تحتفظ بالمقارنة كما هي:
// the faithful rewrite: same shape, same behaviour
function isEligible(user) {
const isAdult = user.age > 18;
const hasSubscription = user.subscribed == true; // kept on purpose, not a typo
const isOutsideFrance = user.country != "FR";
return isAdult && hasSubscription && isOutsideFrance;
}التعليق ليس زينة: بدونه سيأتي مَن «يصلح» == إلى === ويعيد الخطأ من جديد. الكود الغريب عمدًا يحتاج سطرًا يشرح لماذا.
كيف يعمل؟
شكلان: اختيار الوضع ومخاطره، ثم مقارنة سلوك النسختين على القيم نفسها.
شكل 5، متى تستخدم كل وضع، وأين تدخل الأخطاء: القبول بلا قراءة، والمضي بلا فهم.
شكل 6، نفس المدخلات على النسختين: تتفق على الحالات المعتادة وتفترق على القيم «الصادقة» التي ليست true.
ما المطلوب منك بالضبط
المهمة الثانية، خطوة بخطوة
١. أنشئ ملف snippet.js في VS Code والصق الكود الأصلي كما هو.
٢. جرّب الإكمال. ضع المؤشر تحت الدالة وابدأ بكتابة function describeUser(u) { ثم انتظر ثانية. سيظهر نص رمادي، اقرأه قبل أن تضغط Tab.
٣. جرّب المحادثة. افتح اللوحة الجانبية والصق checkUser واسأل: «أعد كتابة checkUser لتكون أسهل على مبتدئ، بلا تغيير ما تفعله. واشرح تغييراتك بلغة بسيطة.»
٤. اسأل أسئلة متابعة حتى تفهم كل تغيير. واسأل تحديدًا: «هل Boolean(u.subscribed) تساوي u.subscribed == true في كل الحالات؟»، وراقب الجواب.
٥. اختبر بنفسك. اكتب خمس حالات وشغّل النسختين وقارن. هذه الخطوة ليست في نص المشروع، وهي الأهم: بدونها تصدّق أن إعادة الكتابة مكافئة.
اعتقاد شائع × الحقيقة
| الاعتقاد | الحقيقة |
|---|---|
| «إذا كان الكود أوضح فهو أصح.» | الوضوح والصحة شيئان. إعادة الكتابة أعلاه أوضح وتغيّر السلوك. اختبر، ثم احكم. |
| «النموذج يعرف نيّتي من الكود.» | يخمّن من النمط. ولهذا يقترح أشياء معقولة تفترض ما لا يوجد في مشروعك. |
«x == true وBoolean(x) سيّان في جافاسكربت.» | == يحوّل الطرفين إلى أرقام؛ وBoolean يسأل عن الصدقية. "yes" == true // false لكن Boolean("yes") // true. |
| «الإكمال السطري أسرع فهو أفضل دائمًا.» | أسرع للكتابة لا للفهم. للمهام التي تحتاج قرارًا، المحادثة أفضل لأنها تشرح. |
| «قبول اقتراح واحد بلا قراءة لا يضرّ.» | يضرّ تراكميًا: الاقتراحات المقبولة بلا قراءة تبني مشروعًا لا تعرف كيف يعمل، ثم يأتي أول خطأ. |
| «ما دام يعمل فلا داعي لاختبار الحالات الغريبة.» | القيم الغريبة تأتي من بيانات حقيقية: نماذج ويب ترجع نصوصًا، وواجهات ترجع 1 أو "true" بدل true. |
جرّب بنفسك
طلبت من المحادثة إعادة كتابة دالة «بلا تغيير ما تفعله»، فأعطتك نسخة أوضح. ما خطوتك التالية؟
سؤال «هل أنت متأكّد؟» يُنتج طمأنة لا دليلًا، والنموذج غالبًا سيؤكّد. الدليل الوحيد تشغيل النسختين على نفس المدخلات، بما فيها الغريبة. وفي هذه الحالة تحديدًا تتفق النسختان على الحالات المعتادة وتفترقان عند subscribed = "yes" وsubscribed = 2.
بطاقات مراجعة سريعة
x == true في جافاسكربت تعني؟"yes" == true = ؟false، لأن "yes" تصير NaN وtrue تصير 1.تحقّق من فهمك
1. اشرح بجملة لماذا "yes" == true // false بينما Boolean("yes") // true.
== يحوّل الطرفين إلى أرقام: true تصير 1 و"yes" تصير NaN، وأي مقارنة مع NaN خاطئة. أما Boolean فيسأل عن الصدقية، وأي نص غير فارغ صادق.
2. متى يكون الإكمال السطري أفضل من المحادثة فعلًا؟
حين تعرف ما تريد كتابته بالضبط وتريد كتابته أسرع: استيرادات، هيكل دالة، حلقة معتادة. يوفّر الطباعة لا التفكير، ولهذا هو ممتاز للتكرار وسيّئ للقرار.
3. (اكتشف الخطأ) قبلت اقتراحًا رماديًا، والآن يقول البرنامج إن دالة غير معرّفة. ما الأرجح؟
النموذج استدعى دالة باسم معقول لا وجود لها في مشروعك، أو موجودة بتوقيع مختلف. هذا أشهر نوع من أخطاء الإكمال، ولهذا نقرأ الاقتراح قبل Tab.
4. سألت «هل أنت متأكّد؟» فأكّد النموذج. هل هذا دليل؟
لا. ثقة النموذج ليست مقياسًا لصحته؛ فهو يتوقّع نصًا مقنعًا لا يتحقّق من واقع. الدليل الوحيد تشغيل الكود. اطلب اختبارًا، لا طمأنة.
5. (قرار) زميلك يستخدم الإكمال فقط ويقول إن المحادثة بطيئة. ماذا تقول له؟
إنه يستخدم أداة واحدة لمهمتين. الإكمال ممتاز لما يعرف الوجهة، لكن حين يتعثّر في خطأ لا يفهمه فالمحادثة أسرع من تخمين الاقتراحات. والفرق الحقيقي: الإكمال يجعلك تكتب أسرع، والمحادثة تجعلك تفهم أكثر، ومن يفهم أكثر يحتاج كتابة أقل.