רשומות

איך התחלנו לנהל שגיאות ב Rust (חלק ג' - anyhow)

תמונה
אם הגעת לכאן במקרה אני ממליץ להתחיל בפוסט הראשון והשני על מנת לקבל רקע. החלק השלישי במסע שלנו לניהול שגיאות היה ההטמעה של anyhow . הספרייה מספקת מספר פיצ'רים נחמדים מאוד שמקלים על הפיתוח ומייפים את הקוד, מייעלים את ניהול השגיאות, ואפילו עוזרים לאחר השגיאה בניתוח שלה. anyhow::Result כמו שבפוסט הקודם ראינו שאפשר להשתמש ב box dyn Error כערך החזרה של השגיאות שלנו וכך לאפשר פעפוע של כל שגיאה שמממשת את Error trait - הספרייה anyhow נותנת לנו type נוח יותר לשימוש ובשימוש בו אנחנו לא צריכים לציין את סוג השגיאה שלנו. אבל יש בעיה קטנה, אם נשתמש ב anyhow באופן הזה אמנם נרוויח את היכולת לבצע פעפוע של כל שגיאה מבלי להוסיף אותה ל TomerCodeError type שהגדרנו בפוסט הקודם, אבל אנחנו מאבדים את השימוש בשגיאה המותאמת אישית שהגדרנו ובכל יכולות ה formatting שהגדרנו לה. בשביל לפתור את הבעיה הזו כל מה שצריך לעשות זה לגרום לשגיאה שאליה anyhow::Result מתייחס להיות אותה שגיאה שהגדרנו. את זה נעשה באמצעות הגדרת alias ל type באופן הבא: כאן בעצם הגדרנו טיפוס Result משלנו, שאיבר השגיאה בו הוא TomerCodeError ועכשי

איך התחלנו לנהל שגיאות ב Rust (חלק ב' - thiserror)

תמונה
בפוסט הקודם דיברתי על הדרך שעשינו מקוד שיכול לקרוס בכל מקום בכל רגע, להפיכת הפרוסס ליציב הרבה יותר באמצעות שימוש ב Result, ופעפוע השגיאות שלנו עם אופרטור `?`. בפוסט הזה נדבר על אחת הספריות המרכזיות בעולם ניהול השגיאות של ראסט ונראה איך היא עוזרת לנו להפוך את ניהול השגיאות שלנו לנוח ויציב הרבה יותר. ברוב המקרים כשנשתמש בכל מיני ספריות צד שלישי וככל שהפרויקט שלנו הופך מורכב יותר אנחנו נתקלים ביותר ויותר סוגי שגיאות בהם אנחנו צריכים לטפל. שימוש ב thiserror הספרייה thiserror עוזרת לנו לעשות סדר בכאוס ומאפשרת לנו להגדיר טיפוס שגיאה משלנו כדי ליצור חוויית ניהול שגיאות אחידה וגנרית בכל הפרויקט. ראסט כשפה נכתבה עם דגש חזק על reducing boilerplate (כלומר - לאפשר למפתחים לא לממש מאפס ספריות וקטעי קוד תשתיתיים שהשפה או ספרייה פשוטה יכולה להנגיש לנו). באותו אופן, גם בעולם ניהול השגיאות קיימות מספר ספריות שמטרתן לגרום לנו לעבוד פחות קשה. thiserror, בין השאר מספקת לנו את ה מאקרו הפרוצדורלי  Error שאפשר להשתמש בו מעל טיפוס השגיאה אותו נרצה לייצר. כאשר נשתמש ב derive Error הטייפ שהגדרנו יממש באופן אוטו

איך התחלנו לנהל שגיאות ב Rust (חלק א' - Result)

תמונה
מבוא גם כשעולם פיתוח התוכנה מתקדם בקצב משוגע, דבר אחד נשאר קבוע - שגיאות.  לא משנה כמה מנוסים נהיה כמפתחים, שגיאות ומקרים לא צפוים תמיד יצוצו לנו. מה שישנה בסופו של יום זה איך אנחנו מטפלים ומנהלים את אותן שגיאות. בפוסט אדבר על הדרך שאני עשיתי והדברים אותם למדתי כמפתח חדש בראסט, ואיך התמודדתי עם העובדה שבראסט אין אקספשנים וגם לא קונספט של try-catch. מה עשינו לפני בשלבים ההתחלתיים של הקודבייס שלנו, כמעט כל האינטרפייסים וכל הפונקציות פשוט החזירו את הטיפוס עצמו איתו רציתי לעבוד. לדוגמה - אם יש לי אובייקט של Registry ופונקציה get_key, אותה פונקציה פשוט החזירה לי String. חשוב לציין, שעצם העובדה ש get_registry_key מחזירה String איננה הבעיה העיקרית כאן, אפשר לראות שמיד לאחר הקריאות ל open_subkey ו get_value של winreg crate מתלוות קריאות ל unwrap עליהן ארחיב ממש עוד רגע, אבל בינתיים רק אגיד שבכל מקום בו אנחנו רואים unwrap, הקוד שלנו יכול לקרוס (panic) במקרה של None או שגיאה - דבר שלרוב לא נרצה שיקרה בפרודקשן. כשהרצנו את המוצר שלנו על data אמיתי ובסקייל גבוה יותר, מהר מאוד התחלנו לקבל קריסות לא

Rust - שימוש ב or ו or_else

תמונה
שימוש ב Option::or_else מול שימוש ב Option::or כשאנחנו עובדים עם Rust אנחנו נתקלים הרבה פעמים במקרים בהם נרצה לטפל בהיעדר ערך, כלומר None, ובשביל זה Option נכנס לתמונה. ראסט נותנת לנו כל מיני דרכים לטפל במקרים הללו ושתיים מהדרכים הנפוצות הן or ו-  or_else . בפוסט הזה נדבר על מה הפונקציות האלו עושות ומתי נרצה להשתמש בכל אחת מהן. מה זה or ו or_else Option::or היא פונקציה שמאפשרת לנו לתת ערך דיפולטי ולהחזיר אותו במידה וה Option הוא None Option::or_else  עובדת דומה מאוד אך מצפה ל Closure (פונקציה) כפרמטר - אותה פונקציה היא זו שתחשב את הערך הדיפולטי במידה וערך ה Option הוא None. מתי נשתמש ב - `or` הפונקציה or תהיה שימושית לנו בעיקר כשיש לנו ערך פשוט, ישיר, שלא יאלקץ לנו זכרון מיותר ושעלות החישוב שלו אינה גבוהה. בדוגמה ניתן לראות שיכנס 0 לערך some_value במידה ויהיה None. הכוח של `or_else` עכשיו, נניח שהיה לנו מקרה בו היינו רוצים לחשב ערך באופן מורכב יותר ולהריץ פונקציה כלשהי בהינתן ערך None, זה יכול להיות חישוב כבד, ביצוע קריאה לבסיס נתונים או כל דבר שאינו מקרה של ערך פשוט. בדוגמה הזו אפשר ל

פולימורפיזם ב Rust

תמונה
התמזל מזלי ובחודשים האחרונים התחלתי לעבוד מאפס על פרויקט חדש ב-Rust, פרויקט שאמור בקרוב לרדת כחלק ממע' ההפעלה Windows. הכניסה ל Rust החזירה לי את התשוקה לחזור לכתוב קצת בבלוג. Rust שונה מאוד מהשפות העיקריות שעבדתי איתן לפני (python ו c#) בהרבה מובנים כמו ניהול הזיכרון, העובדה שאין קלאסים והורשה, ניהול השגיאות, והקומפיילר שעובד שונה לחלוטין. הפוסט הזה ידבר על Polymorphism, אחת התכונות הבסיסיות, העיקריות והחשובות של תכנות מונחה עצמים. ההבנה של הקונספט היא בעיני הכרחית לכל מפתח על מנת לכתוב קוד מודלרי יותר, פשוט יותר לקריאה, וקל יותר להרחבה. יצא לי לדבר לא פעם על Polymorphism בבלוג וכמובן, בכל פעם שהצגתי אותו (ב c# או python) זה היה באמצעות הגדרת מחלקות וביצוע הורשה בניהן. איך מתבצע פולימורפיזם בראסט? במקרה של ראסט אין את הקונספט של מחלקות וגם אין הורשה, אז מה עושים? כאן מגיע הקונספט של traits. באמצעות שימוש ב traits אנחנו יכולים להגדיר סט חתימות של פונקציות ש type יכול לממש (קצת דומה ל interface). כאשר יש לנו מספר structs שכולם מממשים את אותו ה trait אנחנו יכולים להתייחס אליהם באופן

שרת FastApi על דוקר ב10 דקות

תמונה
דרישות: היכרות עם פייתון, עם web frameworks (כקונספט) והיכרות בסיסית עם דוקר. שתי השחקניות החזקות ביותר כיום בתחום ה web frameworks לפייתון הן django ו flask . הפוסט של היום מתעסק בשחקנית החדשה והסקסית בתחום שנכתבה על ידי tiangolo  ובעיני מסמלת את כל מה שטוב ויפה ב open source software. FastApi הוא web framework פייתוני מודרני וחדשני אשר נועד ליצירת APIs. הוא נבנה בעיקרו על הענקיות starlette (לניהול העבודה ב web) ועל pydantic (לולידציית data). הפיצ׳רים העיקריים בהם הכלי מתגאה הם - מהירות (ביצועים), מהירות קידוד , הפחתת באגים (כתוצאה מהפיכת תהליכים שהיו נכתבים ידנית לאוטומטיים), אינטואיטיביות , פשטות , רובסטיות , וסטנדרטיות (עבודה עם JSON schemas ו OpenApi). לכלי קיימות יכולות רבות אותן אני ממליץ לכם לקרוא בעיון בדוקונטציה הרשמית   (דרך אגב, אחת הדוקומנטציות הטובות שיצא לי לראות). בפוסט הזה אתמקד ביצירת API פשוט באמצעות הכלי (מעין hello-world) ובהמשך אגע באיזורים קצת יותר מתקדמים כמו חיבור DB, בדיקות, א-סינכרוניות, authorization ועוד טיפים ויכולות מגניבות בהן יצא לי להתקל. יצירת AP

Azure Functions עם פייתון בקלות

תמונה
יכולת מאוד חזקה ומגניבה שקיימת ב Azure (ובשאר ספקי הענן) היא functions. בפוסט הזה נדבר על מה זה functions, למה זה טוב, מתי נרצה להשתמש בזה, ובנוסף נראה דוגמה פשוטה של functions ב Azure. יש כל מיני דרכים ליצור function ב azure, היום אני אסביר על הקלה והגנרית בעיני - ה CLI. azure cli הוא כלי עוצמתי מאוד שנותן לעשות עם api די אחיד ונוח כמעט כל פעולה שאנחנו רוצים לעשות על סביבת הענן שלנו. מה זה Azure Functions? Azure functions זה שירות ענן שמאפשר לנו הרצה on demand של קטע קוד שנבחר (פונקציה) בעוד שהוא מתחזק עבורנו את כל מה שנדרש על מנת להריץ את הפונקציה הזו. כלומר, איננו צריכים לדאוג לתשתית או לגרסאות מעודכנות של התלויות שלנו. כל שעלינו צריכים לעשות זה לספק את הקונפיגורציה הנדרשת לנו ואת הקוד אותו אנחנו רוצים שירוץ, ו Azure דואג לכל השאר עבורנו.  באמצעות functions ניתן לבנות web APIs, להריץ קוד בעת שינויים בבסיס נתונים, להרשם תורי הודעות ועוד... יתרון נוסף שיש לפונקציות ענן הוא auto-scaling. באופן מובנה, כאשר יגיעו פניות רבות לפונקציה שלנו, מופעים נוספים של הפונקציה יקומו וכשירד הצורך המו