• בלוג
  • אני לא מאמין ששוב עשיתי את הטעות הזאת...

אני לא מאמין ששוב עשיתי את הטעות הזאת...

21/10/2018

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

import React from 'react';

class App extends React.Component {
    render() {
        return
            <div>
                Hello World
            </div>
    }
}

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

import React from 'react';

class App extends React.Component {
    render() {
        return undefined;

            <div>
                Hello World
            </div>
    }
}

הפונקציה הסתיימה בשורת ה return ואף אחד לא הגיע לקוד שמופיע אחרי.

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

/^#/
{
    gsub(".", "-");
}

{
    print;
}

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

# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/usr/local/bin/zsh

התוצאה היתה:

# List of acceptable shells for chpass(1).
------------------------------------------
# Ftpd will not allow users to connect who are not using
--------------------------------------------------------
# one of these shells.
----------------------

---------
--------
--------
-------
---------
--------
------------------

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

/^#/ { print; }

{
  gsub(".", "-");
}

{
  print;
}

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

/^#/ {
  gsub(".", "-");
}

{
  print;
}

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