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

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

טפסים דינמיים בריילס

30/12/2018

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

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

המשך קריאה

הדבר הנכון לעשות

29/12/2018

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

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

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

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

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

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

קוד שאי אפשר לבדוק

28/12/2018

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

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

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

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

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

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

פטריות

27/12/2018

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

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

טיפ גיט: איך לשנות את פורמט הלוג של git

26/12/2018

הפורמט הרגיל של git log ארוך מדי ובפרויקטים גדולים לא מאוד נוח לקריאה. ניסיון לשנות את הפורמט עם אליאס לא ממש עובד. הגדרתי בפרויקט את ה alias הבא:

git config alias.log "log --oneline"

וגיט התעלם באלגנטיות.

הסיבה היא שלא ניתן לדרוס התנהגות רגילה של git באמצעות alias. המשך חיפוש בדוקומנטציה גילה שיש משתנה ב config ששולט על פורמט היומן ואכן הפעלת הפקודות הבאות:

$ git config log.abbrevCommit false
$ git config format.pretty oneline

פתרה את הבעיה ומציגה יומן שנראה כך:

$ git log

5982b5b (HEAD -> master, dev) created a readme file
4945c9c fixed jade template
7b1978d add debug message
943e263 initial commit

הדפסת הודעות לוג לקובץ יומן ב Express

25/12/2018

מורגן הוא מודול תיעוד הבקשות של אקספרס והוא נמצא בכל פרויקט אקספרס שתיצרו עם Express Generator. תוכלו לזהות אותו לפי השורה הבאה בקובץ app.js.

app.use(morgan('dev'));

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

המשך קריאה

תהנה מהדרך

23/12/2018

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

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

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

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

ניצחונות קטנים

22/12/2018

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

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

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

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

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

ביטויים רגולאריים וקסמים של וים

21/12/2018

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

<img src="cat.png" />

והופך אותה לשורה שנראית כך:

<img src="cat-1.png" />

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

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

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

/\V\[0-9]\[0-9]

עדיין אפשר להשתמש בקיצור \d כך שגם החיפוש הזה יעבוד:

/\V\d\d

למצב קצת קסום אנחנו נכנסים עם \M בתחילת הביטוי ומצב זה ממש דומה ל"לא קסום בכלל" מלבד התווים ^ ו $ שלא צריכים שתכתבו \\ לפניהם.

למצב קסום אנחנו נכנסים עם \m בתחילת הביטוי. מצב זה מזכיר מאוד את grep ובו רוב הסימנים המיוחדים יעבדו בלי \\ אבל עדיין יהיו מספר סימנים מיוחדים שכן יצטרכו \\ לפניהם לדוגמא +, ? ו {}.

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

בחזרה לדוגמא מתחילת הפוסט הביטוי הראשון שניסיתי לכתוב בוובינר היה:

:s/\vsrc="(\w+)\.(\w+)"/src="\1-1.\2"/

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

התיקון הכי פשוט יהיה להוסיף \\ לפני סימן השווה ואז נקבל את הביטוי הבא שעובד:

:s/\vsrc\="(\w+)\.(\w+)"/src="\1-1.\2"/

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

:s/\Vsrc="\(\w\+\).\(\w\+\)"/src="\1-1.\2"/
:s/\msrc="\(\w\+\).\(\w\+\)"/src="\1-1.\2"/
:s/\Msrc="\(\w\+\).\(\w\+\)"/src="\1-1.\2"/

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

http://vimdoc.sourceforge.net/htmldoc/pattern.html#pattern

החיים שלי עם ביטויים רגולאריים

20/12/2018

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

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

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

    https://www.tocode.co.il/blog/2015-05-vim-html-image-gallery

  3. עוד כלי שתומך בביטויים רגולאריים הוא גיט ובפרט הפקודה git log שמקבלת פרמטר בשם grep. החיפוש הזה ייתן את כל הקומיטים שההודעה שלהם מתקנת Issue בן שלוש ספרות או יותר.
    $ git log -i -E --grep='(fix|close).*[0-9]{3}'
    
  4. ביטויים רגולאריים יכולים לעשות קסמים כשאתם צריכים החלפה מהירה של מילים בסקריפט. נכון של Bash ולכל סביבה יש את הכלים המיוחדים שלה להחלפות, אבל הייתרון בביטויים רגולאריים שתחביר אחד עובד תמיד: אנחנו נמצא אותם ב awk, sed וכמובן ב grep.

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

    text = 'hello.txt'
    puts text.chomp('.txt') # prints hello
    

    אבל אז אתם עוברים לפייתון ופתאום צריכים לכתוב קוד כזה:

    text = 'hello.txt'
    if url.endswith('.txt'):
        print(text[:len('.txt') + 1])
    

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

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

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

https://www.tocode.co.il/workshops/59