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

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

טכנולוגיות של סוטים

07/04/2020

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

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

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

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

אפשרות שניה היא ללכת על טכנולוגיות עם קהילה קטנה שאין לה ברירה אחרת. זה טריקי כי כשהקהילה קטנה מדי אתה מחוסל, והקהילה יכולה פתאום לגדול ואז עברת למיינסטרים אבל יכול גם לפעמים לעבוד. ריילס היא דוגמא טובה שעברה מזמן את ההייפ שלה אבל עדיין מספקת חווית פיתוח מעולה. אורליה בעולם ה Front End היתה איתנו המון זמן ועדיין מתוחזקת ועובדת טוב למרות היעדר ההייפ. אליקסיר ואיתה פיניקס נותנת פיתרון מלהיב לפיתוח ווב שעדיין לא הגיע למיינסטרים (ואולי לעולם לא יגיע) ו Qt בפיתוח Desktop Applications שכנראה לעולם תגיע.

ריאקט ו SVG הם שילוב מעולה

06/04/2020

אחת הטכנולוגיות הנשכחות של פיתוח Web היא SVG. איכשהו כש Canvas יצאה היא הצליחה לעשות המון רעש, וכמובן ש WebGL היה מלהיב, אבל SVG? זה לא הדבר ההוא שדומה ל XML?. אז כן ולא. תקן SVG יצא לראשונה ב 2001 והשילוב בינו לבין דפדפנים ידע עליות ומורדות לאורך השנים, אבל בשנים האחרונות התמיכה ב SVG בדפדפנים ובספריות פיתוח היא מאוד יציבה ו SVG יכול לתת לכם פיתרון אמין ומהיר להצגה של נתונים בצורה ויזואלית.

בגלל ש SVG נראה כמו אלמנטים רגילים ב DOM אנחנו יכולים ליצור SVG מתוך ריאקט בדיוק כמו שהיינו יוצרים אלמנט רגיל. הקוד ריאקט הבא למשל מצייר מעגל:

function App(props) {
  return (
    <div>
      <svg>
        <circle cx="100" cy="100" r="40" />
      </svg>
    </div>
  )
}

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

svg {
  background: white;
  border: 1px solid black;;
}

circle {
  fill: red;
}

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

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

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

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

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 בשביל הפרונט.

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