הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

כן, לשכתב. אבל חכם.

05/04/2020

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

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

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

ולכן חד משמעית אם אתם בונים היום מערכת חדשה תכתבו אותה כך שיהיה קל לשכתב כל אחד מהמנגנונים וכל אחד מהפיצ'רים שלה. הנה כמה דברים ששווה לשים לב אליהם:

  1. מידע - איזה מידע המנגנון שומר ב DB? איך יהיה אפשר להעביר את המידע כך שישמר במקום אחר? אני מאוד אוהב את הארכיטקטורה של Rails Active Storage בהיבט הזה, שמאפשרת לעבור בקלות בין מקומות אחסון.

  2. קשר עם מנגנונים אחרים במערכת - ככל שיש לי שכל לבנות מנגנונים שה API שלהם לשאר המערכת ברור כך יהיה יותר קל להחליף את הכל. בהיבט הזה כלל טוב הוא לא להשתמש ביותר מנקודה אחת בביטויים שלנו, כלומר להיזהר מקוד שנראה כך:

items[1].name.first

אם יום אחד נרצה להחליף את המימוש של name, אנחנו עדיין נהיה מחויבים לספק פונקציה או משתנה פנימי בשם first וכך אנחנו נעולים על מבנה מסוים.

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

  2. בדיקות, בדיקות ובדיקות. ככל שיש לנו יותר בדיקות מסוג System Tests או Integration Tests על הפיצ'ר, כך אנחנו מרגישים יותר בטוחים כשמגיע הרגע לשכתב.

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

האם תכנות פונקציונאלי הוא בכלל פשוט יותר?

04/04/2020

לימודי תכנות בבתי הספר מתחילים תמיד מתכנות פרוצדורלי: מסבירים מהי תוכנית מחשב, מהו משתנה, מהי לולאה. שפת התכנות אולי משתנה אבל אופן הלימוד נשאר אותו דבר. כלי כמו Scratch ממחיש בצורה מאוד טובה את היסודות של תכנות פרוצדורלי, ויסודות אלה נשארו הדבר הראשון שילדים לומדים כשנחשפים לראשונה לתכנות.

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

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

result = 0
for i in range(1000):
    if i % 5 == 0 or i % 3 == 0:
        result += i

print(result)

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

נשווה את זה רגע לגישה הפונקציונאלית - שם הקוד ייקח כיוון אחר לגמרי, בדגש על חלוקה לפונקציות טהורות. תהיה לנו פונקציית סכום (כבר קיימת ב Python), פונקציה שבודקת אם המספר מתחלק ב-3 או ב-5, פונקציה שמחזירה את כל המספרים בטווח (range) ופונקציה שמחזירה רק את אלה שעבורם פרדיקט מסוים מחזיר אמת (הפונקציה filter). כשמשלבים את הכל יחד ב Python:

def divides_by_5_or_3(n):
    return n % 5 == 0 or n % 3 == 0

res = sum(filter(divides_by_5_or_3, range(1_000)))
print(res)

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

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

קל יותר ללמוד משהו חדש כש...

03/04/2020

  1. אני יודע בוודאות גבוהה שזה הולך לעזור לי בחיים.

  2. אני יודע בוודאות גבוהה שאצליח ללמוד את זה.

  3. כל החברים שלי לומדים את זה (או כבר למדו את זה).

  4. אני יכול לדמיין מה אעשה עם זה אחרי שאדע.

  5. אני מרגיש את הקושי של "לא לדעת את זה" כמעט כל יום.

  6. אני לומד עם עוד אנשים.

  7. יש לנו זמן קבוע ללימוד, ואנחנו עוזרים אחד לשני בזמן הזה (או שיש מדריך שעוזר לכולם).

  8. אני יכול להראות לאנשים אחרים את ההתקדמות.

  9. אני מרגיש בעצמי את ההתקדמות.

לא חייבים את כל ה-9, אבל כמה שיהיו לכם יותר סעיפים מסומנים הסיכוי להצליח בלימוד עולה. ומה שיפה שעל רובם אתם יכולים להשפיע, ואף אחד מהם לא קשור לדבר הספציפי אותו אתם מנסים ללמוד.

פונקציית חץ במחלקה הגיעה לכרום ופיירפוקס

01/04/2020

בשקט בשקט דפדפנים מוסיפים עוד פיצ'רים כולל כאלה שאפילו לא הגיעו לאיפיון הסופי של JavaScript, והבן אדם שמשתמש ב Babel לא יודע בכלל שאפשר להריץ יותר ויותר קוד מודרני גם בלעדיו.

הגילוי של היום היה לגמרי במקרה. כתבתי את הקוד הזה מתוך הרגל והרצתי ב Firefox:

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

הפיתרון הפשוט יותר

31/03/2020

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

הסקריפט הבא למשל הוא סקריפט אנסיבלי שמתחבר לשרת מרוחק ויוצר עליו קובץ עם תוכן מסוים:

---
- name: This is a hello-world example
  hosts: ansibleclient01.local
  tasks:
    - name: Create a file called '/tmp/testfile.txt' with the content 'hello world'.
      copy:
        content: hello world
        dest: /tmp/testfile.txt

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

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

cat << 'END' > /tmp/testfile.txt
hello world
END

בשביל לשנות הרשאות הפעלתי chmod ובשביל להפעיל סרביס כתבתי פשוט systemctl start postgresql. בשביל להריץ פקודה בתור משתמש מסוים אפשר להשתמש ב sudo למשל:

sudo -u ynon -H -i /bin/bash -c "rvm install 2.6.5"

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

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

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

"בוא ננסה את זה" עלול להיות מסוכן

30/03/2020

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

(השוו את זה למשל לחיים הקשוחים של מהנדסי חשמל, שאם יחברו רכיב בצורה לא נכונה עלולים לשרוף את הרכיב או לפוצץ את הבית).

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

שנים הייתי בטוח שהפקודה ll היא פקודה רגילה לגמרי ביוניקס בדיוק כמו ls, עד שיום אחד הגעתי למחשב שלא הוגדר בו ה Alias הזה ולא הבנתי מה קורה. או ב CSS ידעתי שחייבים לציין overflow: auto על אלמנטים שיש בתוכם אלמנטים אחרים, פשוט כי זה עזר למנוע באגים במצבים מסוימים.

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

כלים ופרויקט צד

29/03/2020

גיטהאב נותנים לכם היום מקום לאחסן קוד גם לפרויקט פרטי לגמרי בחינם. אתם יכולים לשתף פעולה עם עוד חבר או חברה, לבנות דף בית ב Github Pages ואפילו להריץ בצורה אוטומטית לגמרי בדיקות אחרי כל קומיט כדי לעבוד כמו המקצוענים.

גם אם אתם לא יודעים לעצב ב Theme Forest תוכלו למצוא עשרות תבניות יפות לאתרים, כל תבנית באזור ה 15$. יכול להיות שתצטרכו להתאים טיפה לפרויקט שלכם אבל זה לא ייקח יותר מיום עבודה.

לינוד ו Digital Ocean ישמחו למכור לכם שרת VPS במחיר של 10$ לחודש שיכול להריץ את הפרויקט שלכם בלי למצמץ. אם אתם לא בקטע של התקנות תוכלו להעלות קצת את הסכום ולקבל מכונה מותקנת מ Heroku. הם גם יוכלו להוסיף לכם אוטומטית מכונות כשהפרויקט יתחיל לצבור תאוצה.

אחרי שיש לכם דף נחיתה אפשר להתחיל לבנות רשימת תפוצה של מתעניינים ראשונים במערכת עם מיילצ'מפ. עד אלפיים נרשמים ראשונים זה חינם.

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

האינטרנט מציע את כל הידע שצריך בשביל הצד הטכני של בניית פרויקט צד, ואם אתם מעדיפים משהו יותר מסודר מנוי לטוקוד יעלה לכם 117 ש"ח לחודש, והקורסים כאן ילמדו אתכם את כל מה שצריך: לינוקס בשביל להתקין את השרת, נוד ומונגו בשביל ה Backend וכמובן HTML, CSS ו React בשביל הפרונט.

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

קוראים לזה JSON

28/03/2020

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

שנים אחר כך כש Webmasters עברו לקרוא לעצמם Front End Developers אנשים לא הבינו בהתחלה מה המקצוע הזה בכלל אומר. לאט לאט ביססו הפרונטאנדיסטים את מעמדם בתור המתכנתים שכותבים בעיקר JavaScript ולא נוגעים ב PHP, בניגוד לוובמאסטרים של פעם שעשו הכל. השם איפשר לאנשים להגיד "אני מתכנת Front End" בצורה שאחרים יבינו על מה אתה מדבר, וכך נוצר תפקיד חדש בתעשיה.

או בואו ניזכר רגע באחד הספרים הכי משפיעים על פרדיגמת ה Object Oriented Programming - הספר Design Patterns של הרביעיה, שבסך הכל נתן שמות לתבניות שכולם השתמשו בהן גם לפני. אבל בזה שהוא נתן להם שמות הוא הפך אותן ללגיטימיות והפך את השיח סביבן לאפשרי.

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

בואו נתכנת יחד

27/03/2020

הי חברים,

אתמול בוובינר Clojure דיברנו על זה שאנחנו לא עושים מספיק Pair Programming ב Zoom. כלומר במשרד בן אדם יכול לגשת לחבר או חברה ולהציע להסתכל יחד על בעיה, ובמעבר לשיגרת הקורונה החדשה הקשר הזה קצת חסר.

אז חשבנו (אני ודני שהעביר איתי את הוובינר) לפתוח קבוצת פיתוח שתתמקד בלימוד Clojure מאפס. הרעיון יהיה להיפגש וירטואלית בזום פעם-פעמיים בשבוע, כאשר בכל מפגש כל אחד מנסה לפתור אתגר תכנותי מסוים שנציג בתחילת המפגש, ולכל אורך המפגש כולם מחוברים בזום באותה שיחה ואפשר לשאול שאלות, להציץ למסכים של האחרים (שרוצים לשתף) או להראות לקבוצה רעיון טוב שהיה לך. סוג של טיפול בעיסוק למתכנתים בתקופת קורונה.

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

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