קוד חכם מדי. קוד טיפש מדי.

06/02/2020

קוד חכם מדי עושה את העבודה אבל צריך להכיר יותר מדי דברים בשביל להבין אותו והרבה אנשים לא יצליחו לתחזק אותו. דוגמת ריילס קצרה מקורס שהעברתי היום כללה טבלא של משתמשים, טבלא של קורסים וטבלא של שיעורים. כל שיעור שייך לקורס וכל קורס שייך למשתמש. השאלה היתה למצוא את רשימת השיעורים של משתמש מסוים, והתשובה החכמה מדי נראית כך:

Lesson.joins(course: :user).select('lessons.*', 'users.id as user_id').where('user_id = ?', user.id)

בשביל להבין את הקוד צריך להכיר מספיק טוב את joins בשביל להבין שיש פה join של שלוש טבלאות. נכון שזה מאוד גנרי ואפשר היה בקלות לבחור כאן משתמשים גם בהתבסס על תנאים אחרים, או אפילו לסנן לפי פרטים של הקורס, אבל כל החוכמה הזאת לא קשורה לשאלה.

גישה הרבה יותר מדויקת תיראה כך:

Lesson.where(course: user.courses)

קוד טיפש מדי עושה את העבודה כמו שצריך אבל לא מכסה את כל המקרים. הביטוי הרגולרי הבא הוא דרך טיפשה מדי כדי לזהות אם מילה מתחילה באות גדולה (שוב ברובי, למרות שביטויים רגולאריים עובדים בכל השפות):

word =~ /^[A-Z]/

זה עובד עבור מילים באנגלית, אבל לא מכסה את כל המקרים ויפול כשנעבור לשפה אחרת. קוד מדויק יותר נראה כך:

word =~ /^\p{Lu}/

והבעיה עם קוד שהוא מדבק: כשיש לכם קוד טיפש מדי במערכת אתם נוטים להגיד שממילא המערכת לא מטפלת במקרים מסוימים אז אפשר להמשיך לכתוב קוד טיפש שמתעלם מאותם המקרים גם במקומות אחרים, וכשיש לכם קוד חכם מדי במערכת אתם לא מבינים אותו ופשוט מעתיקים אותו לעוד מקומות שצריכים דברים דומים בשינויים קטנים.

גם אם הקוד עובד - כשהוא טיפש מדי, או חכם מדי, שווה להתאמץ ולתקן.