يا الله شو بتذكر هداك اليوم… أو بالأحرى، هديك الليلة. كانت الساعة حوالي 2 بعد منتصف الليل، وأنا غرقان في مكتبي بين أكواب الشاي بالمرمية اللي بردت، وبحاول أصلح خطأ غريب في نظام إدارة محتوى كنت شغال عليه لواحد من العملاء. المشكلة كانت إن بعض المستخدمين اللي المفروض يكونوا “محررين” ما كانوا قادرين يوصلوا لصفحة تعديل المقالات، والبعض الآخر اللي هم “مشاهدين” كانوا فجأة بيقدروا يشوفوا خيارات ما لازم يشوفوها. فوضى!
بعد ساعات من البحث والتنقيب في الكود، وصلت لدالة مسؤولة عن التحقق من صلاحيات المستخدم. وفي قلبها، لقيت هاد السطر البريء:
if (user.getRole() == 2 && post.getStatus() == 4) {
// Allow editing
}
وقفت للحظة… “2”؟ وشو يعني “4”؟ يا زلمة شو هالأرقام هاي؟ ما في أي تعليق، ولا أي إشارة توضح المعنى. قلبت المشروع فوقاني تحتاني، فتحت قاعدة البيانات، وصرت أدور في ملفات قديمة عشان أفهم شو القصة. بعد ساعة تانية من المعاناة، اكتشفت إنه الرقم 2 كان بيعني “محرر” (Editor)، والرقم 4 كان بيعني “مسودة مكتملة” (Completed Draft). والمشكلة كانت إنه في مكان تاني من الكود، زميل إلي كان مستخدم الرقم 3 عشان يعني “محرر” بالغلط!
في هديك اللحظة بالذات، وأنا بحكي مع حالي زي المجنون، أدركت إنه المشكلة مش في الخطأ نفسه، المشكلة في “الأرقام السحرية” هاي اللي مزروعة في كل مكان. ومن يومها، أخذت عهد على نفسي: “لا للأرقام السحرية في الكود تبعي”. وهاي القصة هي اللي بدي أحكيلكم عنها اليوم.
ما هي الأرقام السحرية يا أبو عمر؟
ببساطة شديدة، “الرقم السحري” (Magic Number) هو أي رقم بتستخدمه في الكود تبعك بدون ما تعرّفه أو تشرح معناه. هو رقم بيظهر فجأة، “زي السحر”، وبيشتغل، بس محدش فاهم ليش هو هاد الرقم بالذات. ممكن يكون رقم حالة طلب، أو كود خطأ، أو عدد أقصى للمحاولات، أو أي إشي تاني.
شوف هاد المثال:
// Bad example
function processOrder(order) {
if (order.status === 1) {
// ... process new order
} else if (order.status === 2) {
// ... ship the order
} else if (order.status === 8) {
// ... handle returned order
}
}
لو قرأت هاد الكود بعد 6 شهور، أو لو زميلك حاول يفهمه، أول سؤال رح يخطر ببالكم هو: شو يعني 1 و 2 و 8؟ رح تضطروا ترجعوا للتوثيق (إذا كان موجود أصلاً) أو لقاعدة البيانات عشان تفهموا السياق. هاد بالزبط هو تعريف الرقم السحري.
كابوس الأرقام السحرية: ليش هي مشكلة كبيرة؟
يمكن تحكيلي: “يا أبو عمر، ما أنا اللي كاتب الكود وأنا فاهم شو الأرقام هاي”. صدقني، ذاكرتك رح تخونك. وحتى لو ما خانتك، الكود مش إلك لحالك. الكود لازم يكون مقروء ومفهوم لأي حدا في الفريق، وحتى إلك أنت في المستقبل. الأرقام السحرية بتخلق كوابيس حقيقية لعدة أسباب:
1. صعوبة القراءة والفهم (Readability)
الكود النظيف هو كود بيشرح نفسه. الأرقام السحرية بتعمل العكس تماماً، بتخلي الكود غامض ومبهم. قارن المثال السيء السابق بالمثال المحسّن التالي:
// Good example
const ORDER_STATUS = {
NEW: 1,
SHIPPED: 2,
PENDING_PAYMENT: 7,
RETURNED: 8,
};
function processOrder(order) {
if (order.status === ORDER_STATUS.NEW) {
// ... process new order
} else if (order.status === ORDER_STATUS.SHIPPED) {
// ... ship the order
} else if (order.status === ORDER_STATUS.RETURNED) {
// ... handle returned order
}
}
شايف الفرق؟ في المثال التاني، الكود صار بيحكي قصة. أي مبرمج، حتى لو جديد على المشروع، رح يفهم فوراً إنه هاي الدالة بتتعامل مع حالات الطلب المختلفة. ما في داعي للتخمين أو البحث.
2. جحيم الصيانة والتعديل (Maintenance)
تخيل لو قررنا نغير رقم حالة الطلب “مُرتجع” (Returned) من 8 إلى 9 لأسباب تتعلق بقاعدة البيانات. لو كنت بتستخدم الأرقام السحرية، رح تضطر تدور على كل مكان في الكود استخدمت فيه الرقم 8 وتغيره. والمصيبة الأكبر هي: كيف تتأكد إنه كل رقم 8 لقيته بيعني “مرتجع” ومش إشي تاني خالص (مثلاً، الحد الأقصى لعدد المنتجات في السلة)؟ هاي وصفة كارثية للأخطاء.
أما باستخدام الثوابت المُسَمّاة (Named Constants)، فكل اللي عليك تعمله هو تغيير القيمة في مكان واحد فقط:
const ORDER_STATUS = {
NEW: 1,
SHIPPED: 2,
PENDING_PAYMENT: 7,
RETURNED: 9, // <-- التعديل هنا فقط!
};
وهيك، كل الكود اللي بيستخدم ORDER_STATUS.RETURNED رح يتحدث تلقائياً وبشكل آمن.
3. مصدر خفي للأخطاء (A Source of Bugs)
البشر بيرتكبوا أخطاء إملائية (typos). كتابة 8 بدل 7 سهلة جداً، والمترجم (Compiler) أو المفسر (Interpreter) ما رح يساعدك، لأنه بالنسبة إله الرقمين صح. هاد بيؤدي لأخطاء منطقية صعبة جداً في اكتشافها.
لكن لو حاولت تكتب ORDER_STATUS.RETUNED (خطأ إملائي) بدل ORDER_STATUS.RETURNED، لغة البرمجة رح تصرخ في وجهك فوراً وتحكيلك إنه هاد المتغير مش موجود. أنت حولت خطأ منطقي صامت إلى خطأ برمجي واضح وسهل الإصلاح.
الحل السحري الحقيقي: الثوابت المُسَمّاة والتعدادات (Enums)
الحل، زي ما شفنا، هو إنك “تعمّد” كل رقم في الكود تبعك. أعطيه اسم ذا معنى وخزّنه في متغير ثابت (constant).
نصيحة من ختيار برمجة: أي رقم (غير الصفر والواحد في سياقات معينة جداً) بتكتبه مباشرة في الكود هو مرشح ليكون “رقم سحري”. اسأل حالك دايماً: “هل هاد الرقم إله معنى بزنس؟”. إذا الجواب نعم، أعطيه اسم فوراً.
مثال بلغة Python
في بايثون، المتعارف عليه هو استخدام متغيرات بأحرف كبيرة للثوابت.
# Before
def check_permission(user_level):
if user_level == 3:
print("Admin access granted")
# After
ADMIN_LEVEL = 3
def check_permission(user_level):
if user_level == ADMIN_LEVEL:
print("Admin access granted")
# Even better with Enums for grouping related constants
from enum import Enum
class UserRole(Enum):
GUEST = 1
MEMBER = 2
ADMIN = 3
def check_permission_enum(user_role):
if user_role == UserRole.ADMIN:
print("Admin access granted")
مثال بلغة Java
لغة Java بتوفر أداة قوية جداً اسمها enum (التعداد)، وهي الخيار الأفضل دايماً للحالات اللي زي هيك.
// Before
public class Post {
public void setStatus(int status) {
if (status == 4) { // What is 4?
// ...
}
}
}
// After (using Enums)
public enum PostStatus {
DRAFT,
IN_REVIEW,
PUBLISHED,
ARCHIVED; // The underlying numbers are handled automatically!
}
public class Post {
public void setStatus(PostStatus status) {
if (status == PostStatus.PUBLISHED) {
// ... much clearer!
}
}
}
نصائح عملية من خبرتي
- عوّد حالك: اجعلها عادة عندك. أول ما تبدأ مشروع جديد، أنشئ ملف خاص للثوابت (e.g.,
constants.js,config.py) وابدأ بوضع أي قيمة ثابتة فيه. - لا تستثني الأرقام “الواضحة”: حتى الأرقام اللي بتبين واضحة زي
24في اليوم أو100للنسبة المئوية، الأفضل تعطيها اسم.const PERCENTAGE_MAX = 100;أوconst HOURS_IN_A_DAY = 24;بيضيف سياق وبيسهل التعديل لو تغيرت المتطلبات (مثلاً، حسابات على كوكب المريخ!). - استخدم التعدادات (Enums) كلما أمكن: إذا كانت لغة البرمجة تدعمها، فالتعدادات هي الحل الأمثل لأنها بتجمع الثوابت المتعلقة ببعضها وبتوفر أمان من ناحية النوع (type safety).
- مراجعة الكود (Code Review): اجعل البحث عن الأرقام السحرية جزء أساسي من عملية مراجعة الكود. لما تراجع كود زميلك وتلاقي رقم غامض، لا تخجل واسأله: “شو هاد الرقم؟ خلينا نعطيه اسم”. هاي ثقافة فريق بتخلي الكود أفضل للجميع.
الخلاصة يا جماعة الخير 🏁
الأرقام السحرية يمكن تبين كاختصار بسيط وأنت بتكتب الكود، لكنها في الحقيقة دين بتراكم عليك وعلى فريقك. هي قنبلة موقوتة بتخلي الكود صعب القراءة، وكابوس في الصيانة، ومليء بالأخطاء المحتملة.
الاستثمار في كتابة كود نظيف عن طريق إعطاء أسماء واضحة للثوابت هو واحد من أفضل القرارات اللي ممكن تتخذها كمبرمج. هو استثمار في مستقبلك، ومستقبل مشروعك، وفي صحتك النفسية كمان لما تيجي تصلح الأخطاء في نصاص الليالي. 😉
تذكروا دايماً: الكود النظيف مش رفاهية، هو أساس البرمجة الاحترافية. يلا، شدوا حيلكم!