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

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

טיפ באש: השתמשו ב null glob כשצריך

16/08/2021

את הלולאה הקצרה הזאת כתבתי בסקריפט בלי לחשוב יותר מדי:

#!/bin/bash -e

for json_file in /data/*
do
  echo "Importing JSON file $json_file"
  python import_json.py "$json_file"
  echo "-- Done"
done

ולמה בלי לחשוב? כי אם הסקריפט import_json.py ינסה לפתוח את הקובץ שהוא מקבל לקריאה, והתיקיה ריקה, אנחנו נקבל את השגיאה:

FileNotFoundError: [Errno 2] No such file or directory: '/data/*'

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

# this will print all the files in /etc
$ echo /etc/*

# but this will just print "/data/*"
$ echo /data/*

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

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

$ shopt -s nullglob
$ echo /data/*

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

#!/bin/bash -e

shopt -s nullglob

for json_file in /data/*
do
  echo "Importing JSON file $json_file"
  python import_json.py "$json_file"
  echo "-- Done"
done

הפעם הסקריפט לא ינסה לפתוח קובץ עם השם המוזר /data* ופשוט לא יבצע אף פעם את גוף הלולאה כי באמת אין קבצים שמתאימים לביטוי.

האבסורד של טכנולוגיות נגישות

15/08/2021

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

תקופה ארוכה PHP היה נגיש כי מספיק היה לשים קובץ PHP על השרת כדי לקבל אתר דינמי (בניגוד ל setup המסורבל של CGI Scripts שהיו לפניו). jQuery היה נגיש כי היה מאוד קל למתכנתים להבין איך להשתמש בו ולבנות קוד שעובד. ריילס ב 2005 היה מאוד נגיש כי הוא דיבר לאותם מאוכזבי PHP שחיפשו יותר סדר בקוד שלהם, אבל לא הרגישו בנוח לעבור ל Java או .NET, אנגולר1 היה יותר נגיש מ Backbone ו Ember למתכנתי Backend כי הוא איפשר להם "לדלג" על לימוד עולם ה Front End ולכתוב דברים סבירים בלי להבין את המכניקה שמתחת, והיום Vue יותר נגיש מ React או Angular מסיבות דומות.

האבסורד הוא שכמעט לכל טכנולוגיה נגישה מגיע בסוף רגע "ההתפכחות", שבו אנחנו מבינים שרק בגלל שהיה קל להתחיל לעבוד בטכנולוגיה מסוימת לא בהכרח הופך אותה לטובה. ב Angular1 זה היה עם הפופולריות של ג'ון פאפא וה Style Guide המפורסם שלו. ריילס הפכה למסורבלת באזור 2010 ככל שעלתה הפופולריות של Node.JS ומיקרו פריימוורקס בצד שרת ו jQuery הפסיקה להיות אטרקציה כשמתכנתים "רציניים" התחילו להביא לעולם ה Front End רעיונות של תכנות מונחה עצמים ואנקפסולציה שהם הכירו מסביבות אחרות, במיוחד החל מ 2008 עם הספר JavaScript The Good Parts.

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

מדריך Vue למתחילים - חלק 6 - יישומי Single Page Apps עם Vue Router

ויו היא ספריה לפיתוח יישומי צד-לקוח מורכבים. בשבועות האחרונים אני מפרסם לאט מדריך Vue למתכנתי Front End שרוצים להתחיל לעבוד עם הספריה. עד כה פורסמו הפרקים:

  1. פרק 1 - פיתוח קומפוננטה ראשונה

  2. פרק 2 - תקשורת בין קומפוננטות

  3. פרק 3 - תבניות דינאמיות

  4. פרק 4 - ממשק ההרכבה Composition API

  5. פרק 5 - דוגמת פיתוח נגן YouTube ב Vue

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

המשך קריאה

זה יעבוד בסוף

13/08/2021

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

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

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

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

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

איפור ואבטחת מידע

12/08/2021

הם לא הולכים ביחד, והבעיה שהאיפור רק מחמיר את המצב. נפלתי במקרה על הדף הזה היום: https://docs.npmjs.com/docker-and-private-modules

זה מתוך התיעוד של npm. הדף מסביר איך ליצור קובץ .npmrc בתור Docker Image, למשל בשביל למשוך אימג' ממאגר פרטי. הם ממליצים להשתמש ב Dockerfile הבא:

FROM risingstack/alpine:3.3-v4.3.1-3.0.1
ARG NPM_TOKEN
COPY .npmrc .npmrc
COPY package.json package.json
RUN npm install
RUN rm -f .npmrc
# Add your source files
COPY . .
CMD npm start

ובתבנית הבאה עבור npmrc:

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

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

בשביל המשחק לקחתי את ה Dockerfile שלהם ובניתי ממנו אימג' וגם פירסמתי אותה ב Dockerhub. תראו אם תצליחו לגלות מה הערך של NPM_TOKEN בדוגמה שלי: https://hub.docker.com/layers/ynonp/dtest/latest/images/sha256-7eb4139557b15d6dd86cd5d9511863aaa03cb4271f3f799d701d5c80aa357575?context=explore&tab=layers.

איך אני מריץ שאילתת SQL מתוך הדפדפן?

11/08/2021

ש: איך אני מריץ שאילתת SQL מתוך הדפדפן?

ת: אתה לא

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

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

מדריך Vue למתחילים - חלק 5 - בואו נבנה נגן YouTube ב Vue

ספריית Vue היא ספריית JavaScript לפיתוח מבוסס קומפוננטות. היא נחשבת לאחת מספריות הפיתוח הפופולריות היום יחד עם React ו Angular. מה שמייחד את Vue הוא המאמץ של כותביה לבנות ממשק שיהיה מאוד ידידותי לאנשים חדשים ויאפשר כניסה קלה לעולם של קומפוננטות.

פרק זה הוא הפרק החמישי במדריך. אלה החלקים הקודמים:

  1. פרק 1 - פיתוח קומפוננטה ראשונה

  2. פרק 2 - תקשורת בין קומפוננטות

  3. פרק 3 - תבניות דינמיות

  4. פרק 4 - ממשק ההרכבה Composition API

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

המשך קריאה

חידת ריאקט: קומפוננטות, אפקטים וסדר פעולות

09/08/2021

הקוד הבא מתאר שתי קומפוננטות, שתיהן קוראות ל useEffect:

import { useEffect, useState } from "react";

export default function Page(props) {
  useEffect(function () {
    document.title = "Page";
  }, []);

  return <Content />;
}

function Content(props) {
  const [title, setTitle] = useState(document.title);

  useEffect(function () {
    setTitle(document.title);
  }, []);

  return <p>Page title = {title}</p>;
}

והשאלות:

  1. איזה אפקט ירוץ קודם?

  2. מה יהיה תוכן העמוד אחרי רינדור הקומפוננטה Page?

  3. איך אפשר לשנות את סדר האפקטים ולקבל תוצאה שונה על העמוד?

פרויקט צד

08/08/2021

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

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

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

  1. בעבודה אני כותב דברים בטכנולוגיה X; פרויקט צד מאפשר לי לגלות טכנולוגיות חדשות.

  2. בגלל שאני אוהב את הכלבים שלי אני נהנה לכתוב מוצרים שמשמחים אותם.

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


תחביב. שם עצם - זכר. עִסּוּק מְסֻיָּם שֶׁאָדָם עוֹסֵק בּוֹ מִתּוֹךְ חִבָּה וְעִנְיָן בִּשְׁעוֹת הַפְּנַאי מֵעֲבוֹדָתוֹ, עִסּוּק שֶׁלֹּא לְשֵׁם פַּרְנָסָה אוֹ רְוָחִים, “הוֹבִּי”: פְּלוֹנִי בַּעַל תַּחְבִּיב שֶׁל אִסּוּף בּוּלִים. הוּא עוֹסֵק בְּצִיּוּר כְּתַחְבִּיב.

משימות קשות

07/08/2021

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

.. שלוש שעות יותר מאוחר

  • נראה לי שהצלחתי לבנות סקריפט קטן שמריץ כל קובץ בדיקות בתהליך אחר!

... שבועיים יותר מאוחר

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

... שלושה חודשים יותר מאוחר

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

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