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

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

אצלי אין באגים

12/07/2019

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

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

  def perform(workshop_instance)
    return if (workshop_instance.date - Time.zone.now) > 1.hour
    return if workshop_instance.passed?

    zoom = Zoom.new
    emails = zoom.meeting_registrants(workshop_instance.zoom_id)
    NotificationsMailer.webinar_reminder(workshop_instance, emails).deliver_now
  end

חשבתי - יש פה 5 שורות... מה כבר יכול להשתבש?

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

require "rails_helper"

RSpec.describe WebinarReminderJob, :type => :job do
  let (:wi) { workshop_instances(:one) }

  before(:each) do
    wi.create_zoom_meetup
  end

  after(:each) do
    wi.delete_zoom_meetup
  end

  describe "#perform" do
    it "sends an email to workshop participants" do
      zoom = Zoom.new
      zoom.add_user(wi.zoom_id, email: 'testuser@gmail.com', first_name: 'test', last_name: 'user')

      WebinarReminderJob.perform_now(wi)

      expect(ActionMailer::Base.deliveries.last.to).to eq(['testuser@gmail.com'])
    end
  end
end

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

כמה נקודות לגבי הבדיקה ששווה לשים לב אליהן, גם אם לא מכירים רובי:

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

  2. יש Mock למנגנון המייל - המייל לא באמת נשלח למשתמש הבדיקה. באופן אוטומטי בגלל שרצים בטסט ריילס שומר את המייל שהיה אמור לשלוח בתוך אוביקט בשם ActionMailer::Base.deliveries. המוק הזה נוצר אוטומטית כחלק מהפריימוורק לכן אני שמח להשתמש בו.

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

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

פשוט כי בא לי להחליף

11/07/2019

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

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

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

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

זה לא בשבילך

10/07/2019

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

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

  1. לבטל את טופס צור קשר. מי שבאמת רוצה ימצא דרך להגיע.

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

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

  4. לפרסם באתר את המחיר, ושיהיה כפול מכל מחיר אחר שאתם מוצאים ברשת.

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

איך לתקן כל באג בעולם

09/07/2019

מסתבר שלתקן באגים זה דבר ממש קל. התהליך מורכב בסך הכל מ-3 שלבים:

  1. מתחילים בכתיבת טסט שנכשל בגלל הבאג.

  2. מתקנים את הבאג.

  3. רואים שהטסט עובר ועושים קומיט.

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

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

08/07/2019

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

  1. האקר זדוני מקלקל שורה בקובץ ועושה קומיט.

  2. חבר טוב בטעות מוחק את הקובץ כי משהו שם נראה חשוד.

  3. החבר מיד מבין שטעה והקובץ דווקא היה חשוב, אז מפעיל revert כדי להחזיר את הקובץ.

  4. בפעם הבאה שנפעיל גיט בליים נקבל את טביעות האצבע של החבר על כל השורות.

הנה הכל בהמחשה על מאגר לדוגמא. המאגר כרגע כולל רק קובץ אחד בשם demo.txt:

$ git log --oneline
193c20a (HEAD -> master) initial commit

$ ls
demo.txt

$ cat demo.txt
hello
this is a demo file
created by mr. nice guy

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

# now evil hacker arrives
$ sed -i .bak 's/mr. nice guy/evil hacker/' demo.txt
$ rm demo.txt.bak
$ git commit -a -m 'hahaha'

$ git log --oneline
c4a9b1b (HEAD -> master) hahaha
193c20a initial commit

ואחרי זמן מה חבר נחמד בטעות מוחק את הקובץ ומחזיר אותו עם revert:

$ git rm demo.txt
$ git commit -m 'oops'
$ git revert HEAD
$ git log --oneline

5bc7d72 (HEAD -> master) Revert "oops"
0f96ad4 oops
c4a9b1b hahaha
193c20a initial commit

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

$ git blame demo.txt
5bc7d722 (ynonp 2019-07-07 15:24:36 +0300 1) hello
5bc7d722 (ynonp 2019-07-07 15:24:36 +0300 2) this is a demo file
5bc7d722 (ynonp 2019-07-07 15:24:36 +0300 3) created by evil hacker

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

אני רוצה לדלג על 5bc7d722 אז אעביר את זה שלפניו:

$ git blame 5bc7d72~ demo.txt
fatal: no such path demo.txt in 5bc7d72~

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

$ git blame 5bc7d72~~ demo.txt
^193c20a (ynonp 2019-07-07 15:20:43 +0300 1) hello
^193c20a (ynonp 2019-07-07 15:20:43 +0300 2) this is a demo file
c4a9b1b5 (ynonp 2019-07-07 15:23:06 +0300 3) created by evil hacker

וכך מגלים שהקומיט הבעייתי הוא c4a9b1b5.

תשעה טיפים לכתיבת Shell Scripts טובים יותר

07/07/2019

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

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

המשך קריאה

תרגום

06/07/2019

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

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

וכמו שתשובות יכולות להופיע בשפה שאנחנו לא מכירים הן גם יכולות להופיע בטכנולוגיה שאנחנו לא מכירים. אנחנו מחפשים פיתרון לבעיה ב Python2 וכל התשובות באינטרנט מראות את הפיתרון ב Python3. אנחנו מחפשים תשובה לבעיה ב React וכל מה שמצליחים למצוא זה פיתרון ב jQuery לאותה בעיה.

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

הסכנה הכי גדולה לעסק שלכם

05/07/2019

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

ואחרי 8 שנים של פרילאנס אני כבר יודע להגיד שזה הפחד הלא נכון.

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

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

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

הגנת CSRF ב Express לעומת Rails

04/07/2019

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

ב Express בשביל להגן על האתר שלכם ממתקפת CSRF אתם תצטרכו:

  1. לדעת שאתם צריכים הגנת CSRF ולחפש את הספריה בגוגל.

  2. להתקין את הספריה.

  3. להיזכר שאתם צריכים להגן גם על ה API שלכם ולמצוא את הספריה cors-gate, ואז להתקין גם אותה.

  4. להפעיל את שתי הספריות לפי ההוראות בתיעוד שלהן באמצעות הוספת Middlewares.

  5. להוסיף בכל אחד מהטפסים במערכת את ה CSRF Token.

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

בריילס כל זה קורה אוטומטי בשבילכם ומופעל By Default בכל פרויקט חדש.

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

קוד שמתעד את עצמו

03/07/2019

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

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

המשך קריאה