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

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

קוד שעה ביום

10/08/2020

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

כי חוץ ממנו יש את הקוד שאנחנו כותבים כדי ללמוד:

  1. את הקוד שראיתי בוידאו ואני מקליד כדי לראות איך זה עובד.

  2. את הקוד שמצאתי בספר ואני מקליד וגם משנה אותו קצת.

  3. את הקוד בשביל לפתור חידת תכנות שמצאתי.

  4. את הקוד שאני כותב כדי לענות על שאלה של תלמיד, או של מישהו אקראי מ Stack Overflow.

  5. את הקוד שאני כותב כדי ללמוד שפת תכנות חדשה.

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

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

תוצאה ראשונה בגוגל

09/08/2020

לפעמים התשובה הטובה ביותר תהיה בתוצאה הראשונה בגוגל. לפעמים היא תהיה ב Stack Overflow. לפעמים היא תהיה באיזה בלוג פוסט של בלוגר מפורסם ולפעמים בפוסט של בלוגר שאף פעם לא שמעתם עליו.

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

  1. לפעמים באמת התשובה הטובה ביותר היא לא התוצאה הראשונה. וזה קורה לעתים יותר קרובות ממה שהייתם מדמיינים.

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

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

קומיטים הם לנצח

08/08/2020

אחד הרעיונות שלקח לי המון זמן להבין ב git אבל אחרי שהבנתי שינה לגמרי את כל מה שעשיתי הוא הכלל הבא:

קומיטים הם לנצח, בראנצ'ים הם רק מדבקות

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

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

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

$ git log --oneline
4980b49 (HEAD -> master) initial commit

$ git commit --amend -m 'initial commit - take 2'
$ git log --oneline
392bc0d (HEAD -> master) initial commit - take 2

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

$ git log --oneline 4980b49
4980b49 initial commit

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

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

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

$ git switch -c history 4980b49
$ git log --oneline
4980b49 (HEAD -> history) initial commit

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

$ git branch -f master history
$ git switch master
$ git branch -f history 392bc0d

והנה הסיפורים אחרי השינוי:

$ git log --oneline history
392bc0d (history) initial commit - take 2

$ git log --oneline master
4980b49 (HEAD -> master) initial commit

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

שש מאות ששים ותשע שורות

07/08/2020

הפעלתי היום npm run eject בתוך יישום שנוצר עם create-react-app וקיבלתי קובץ וובפאק של 669 שורות ועוד 6 קבצי הגדרות קטנים יותר.

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

אז מה קיבלנו שם אתם שואלים? סקירה זריזה של הדברים שקפצו לי לעין:

  1. קובץ manifest.json שממש יעזור לכם אם השרת שלכם צריך לבנות דינמית את ה HTML ולשתול בו בצורה דינמית את קבצי הסקריפט (אה, אתם מגישים קובץ HTML סטטי? תמשיכו ללכת אתם לא צריכים את זה).

  2. הגדרות אליאס לריאקט נייטיב (אה, אתם לא כותבים ריאקט נייטיב? לא משנה, שיהיה לכם)

  3. מנגנון שגורם ל webpack לא לטעון קבצי locale גדולים מספריית moment.js (חשוב, מה אתם לא משתמשים ב moment.js?).

  4. מנגנון file-loader שמאפשר לנו לבצע import לקבצים רגילים מתוך קוד ה js שלנו כדי לקבל את שם הקובץ (למשל בשביל לשלב תמונות בתוך javascript).

את רוב הדברים האלה לא הייתי מכניס לקובץ webpack רגיל של הפרויקט. אולי אוסיף אותם כשאתקל בבעיה מסוימת או בצורך מסוים, אבל בטח לא בצורה גורפת. אבל הבעיה היותר גדולה עם 669 שורות של קונפיגורציה היא שאנשים רואים את הבלוק הזה ופוחדים לשנות אותו, וכך במקום להתאים את הגדרות הבניה למה שאני באמת צריך אנשים מחפשים לבנות פיתרונות ומעקפים רק בשביל להישאר בתוך ה create-react-app.

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

איך לצמצם Boilerplate ב Redux - חלק 3

06/08/2020

בשני החלקים הקודמים למדנו איך לצמצם Boilerplate ביישום Redux באמצעות טיפול ב Action Creators וב Reducer. היום אני רוצה לדבר על הקומפוננטות ולהראות איך לכתוב הרבה פחות קוד בתוך קומפוננטה שמחוברת ל Redux ועדיין לקבל בדיוק את אותה תוצאה.

המשך קריאה

כאלה דברים פשוט יכולים לתסכל

05/08/2020

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

המשך קריאה

קורסים שמפחידים אותי

04/08/2020

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

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

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

(מה זה תבניות לא נכונות? לדוגמא בשפה כמו C זה יהיה כמו ללמד את malloc בלי ללמד את free. ב JavaScript זה יהיה ללמד את הפונקציה document.write, ועוד דברים רבים בסגנון).

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

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

איך לצמצם Boilerplate בקוד Redux באמצעות ES6 Proxy

02/08/2020

לפני כמה ימים גדי העיר כאן שאחת הבעיות המרכזיות עם Redux היא כמות קוד ה Boilerplate שצריך לכתוב. לדעתי הקשיים בעבודה עם Redux הם אחרים אבל ההערה הזאת דחפה אותי לשחק קצת עם הכלים כדי לכתוב קוד רידאקס קצר יותר. אחת התוצאות היא התבנית הקצרה הבאה לחסכון בקוד ה Action Creator (אני מקווה בהמשך לפרסם עוד כמה תבניות מועילות ברוח זו).

המשך קריאה

הנתיב השמח

01/08/2020

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

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

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

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

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