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

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

חידת דוקר: שינוי הרשאות

23/05/2022

בתיקיה חדשה ניצור 3 קבצים. הראשון הוא Dockerfile:

FROM ubuntu:22.04

WORKDIR /app

COPY . .

RUN chmod +x /app/startup.sh

CMD ["/app/startup.sh"]

השני נקרא startup.sh ומכיל את התוכן הבא:

#!/bin/bash

echo Hello World

והשלישי docker-compose.yml עם התוכן הבא:

version: "3.9"

services:
  app:
    build: .
    volumes:
      - .:/app

אני מפעיל:

$ docker compose build
$ docker compose run

ומקבל את השגיאה:

[+] Running 1/1
 ⠿ Container chmod-in-run-app-1  Recreated                                                                         0.2s
Attaching to chmod-in-run-app-1
Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/app/startup.sh": permission denied: unknown

מה קרה שם? איך נתקן?

המשך קריאה

לא רואה את זה

22/05/2022

לא רואה את זה

לא רואה את זה

לא רואה את זה

לא רואה את זה

לא רואה את זה

רואה את זה

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

מהר מאוד הם מגלים שידע לא מדבק.

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

הערכה טכנולוגית מתחילה ב Trade Offs

21/05/2022

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

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

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

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

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

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

נ.ב. הסקירה הזאת על ראסט: https://www.bunniestudios.com/blog/?p=6375 היא דוגמה מעולה לסקירה טכנולוגית שמציגה גם את העלויות ולא רק יתרונות מובהקים או חסרונות מובהקים.

החיים אחרי בייבל

20/05/2022

את AMD הכרתי באמצעות require.js שהיתה להיט באזור שנת 2012 (מה שנקרא, עובד ב IE6) וכנראה גם קצת קודם. מה ש require עשתה היה לאפשר לכם לכתוב בתוך קובץ JavaScript אחד פקודה שתטען קובץ JavaScript אחר. נכון, לפני require היתה את dojo שעבדה על אותו מנגנון אבל זה כבר למתקדמים.

ל Require היה כלי אופטימיזציה שלוקח קבצים שכתובים ב AMD ומאחד אותם יחד לקובץ אחד וככה מצליח לשפר את זמן טעינת העמוד, כי צריך לשלוח פחות קבצים לדפדפן. אחרי זה הגיעו grunt, gulp, webpack ו babel ואנחנו עברנו להשתמש בכתיב ה import/export ולהריץ קוד על קבצי ה JavaScript בתוך שלב האופטימיזציה.

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

נגלגל קדימה ל 2022 והעולם השתנה שוב. היום דפדפנים תומכים תמיכה מלאה ב ES Modules ובטעינת קובץ JavaScript מתוך קובץ אחר. בנוסף תקן HTTP/2 תומך ב Server Push שאומר שאין ייתרון מבחינת ביצועים ל Bundling.

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

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

המשך קריאה

מדריך: איך לבדוק פרויקט vite עם vitest

19/05/2022

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

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

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

המשך קריאה

טיפ גיט: נגמלים מ push

18/05/2022

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

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

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

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

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

$ git branch --unset-upstream

ועכשיו ניסיון לעשות push ייכשל עם ההודעה:

fatal: The current branch mybranch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin mybranch

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

$ git push origin mybranch

והיתרון הוא שכבר אי אפשר לכתוב בטעות git push מיד אחרי קומיט ואחרי זה לאכול את הלב כשצריך לתקן שגיאת כתיב.

מתי תורי? סקריפט פייתון פשוט לחישוב זמן המתנה

17/05/2022

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

המשך קריאה

זה ייקח רק חמש דקות

16/05/2022

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

אבל אלה רק חלק קטן מהמצבים.

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

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

#!/bin/bash

count=0

ls | while IFS= read -r line;
do
  (( count++ ))
done

echo $count

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

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

שלושה טריקים של foreach שכבר לא כדאי לעשות

15/05/2022

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

המשך קריאה

בואו נמצא מספרים שמחים עם Elixir

14/05/2022

מספר שמח הוא מספר שסכום ריבועי הספרות שלו בסוף יוצא 1. מספר עצוב הוא מספר שסכום ריבועי הספרות שלו לא יוצא 1, לא משנה כמה פעמים מעלים בריבוע ומחברים. ככה יוצא ש 7 הוא מספר שמח, כי כשמעלים אותו בריבוע מקבלים 49, וכשמעלים בריבוע את שתי הספרות של 49 מקבלים 16 ו 81 שסכומם יוצא 97, ממשיכים עוד סיבוב ומקבלים את 49 ו 81 שסכומם הוא 130, ועכשיו אנחנו מתקרבים למשהו כי 3 בריבוע זה 9 ו 1 בריבוע נשאר 1, יחד הם נותנים 10, שסכום ריבועי הספרות שלו הוא פשוט 1 בריבוע ועוד אפס בריבוע כלומר המספר 1.

לעומתו 4 הוא מספר עצוב כי בריבוע הוא נותן 16, וכשמעלים בריבוע את 1 ו 6 מקבלים 1 ו 36, שזה יחד 37, הסכום הבא הוא 58, אחרי זה 89, ואז 145, 42, 20 ושוב 4.

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

המשך קריאה