ארכיון חודשי: מאי 2011

שגיאה, כישלון וחריגה (חלק ראשון)

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

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

  • שגיאה – היא מצב בו התוכנה/הקוד אינו מממש דבר מה שכן מתבקש ממנו לעשות.
  • כישלון – הוא חוסר היכולת לבצע את המשימה שהתוכנה עצמה אמורה לבצע
  • חריגה – היא מצב בו בוצע משהו בלתי צפוי בריצת התוכנה.

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

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

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

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

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

אתר עם שפה

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

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

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

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

Playing with web frameworks

Foreword

I'm researching several web frameworks in order to create a web application that I need to, that also should work as a web site on the Internet, and will have API to integrate things into other web-sites, if clients does not want to use that site.

For the task I started with two frameworks:

  1. fpWeb – aka fcl-web
  2. django

I do not want to try Rails, because I find the logic behind it very disturbing. The Rails framework rewrite the language, rather then adding libraries to use. I think that it is not the proper way to write libraries. So I decided not to try it at all, even though I really love the Ruby language itself.

fpWeb

So I started testing fpWeb, and I must say that it takes a while to get used to it and the way it does things, but once I figured out the basics, I find it really enjoyable to write a CGI (I always hate to write html/css stuff though, and that's regardless of the language for the server side) application.

fpWeb works in very different mindset then most modern web frameworks I have ever worked with so far. On one hand it appears that everything chosen for you, that is the template engine, session engine etc.. But  on the other hand, you can actually use what ever you want, just decide on something and go for it. להמשיך לקרוא

סקייפ לאסטריסק – הסוף

סקייפ לאסטריסק הוא תוסף עבור אסטריסק אשר מפותח על ידי דיג'יום ובשיתוף פעולה של חברת סקייפ. התוסף מאפשר לאסטריסק להיות "לקוח" ברשת סקייפ ולהצליח להכניס ולהוציא שיחות בפרוטוקול של סקייפ, ובנוסף להוציא שיחות טלפון רגילות באמצעות Skye-Out.
דיג'יום הודיעו כי חברת סקייפ לא מחדשת את ההסכם עם החברה עבור Skype For Asterisk, ולכן לא ניתן יהיה לרכוש או להפעיל את החיבור החל מה26 ליולי השנה.

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

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

גרסת 2.4.4 של FPC יצאה

בשעה טובה ומוצלחת יצאה אתמול אחת הגרסאות הכי משמעממות של FPC אי פעם – גרסה 2.4.4.

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

  • עבודה מול XML
  •  טיפול בעבודה טובה יותר מול SQLite
  • שיפור עבודה ויצור של קבצי CHM
  • ותוספות רבות עבור fppkg ו fpmake.

ניתן לראות למה כמה מהתנהגויות השתנו.

ניתן לראות את כל השינויים שנעשו כאן.

ואתם מוזמנים גם להוריד את הגרסה החדשה.

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

URI, URL, URN

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

למשל הרבה הרבה מימושים של ספריות שאמורות לפרש URI בעצם מפרשות רק URL. בעוד שאם הולכים להגדרה של URI כ RFC מגלים שצריך לממש הרבה מעבר.

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

אז למה יש כל כך הרבה בלבול בין הדברים ? ובכן הרבה אנשים לא מבינים לעומק מה כל אחד מ3 המונחים האלו אומרים, ומתייחסים ל URI כאל URL, ושוכחים מהחלק של URN בכלל, וזה במקרה הטוב.

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

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

URN היא הדרך להגיד מה השם שאנחנו מחפשים.

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

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

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

אה, וזה סתם פוסט להוציא קצת תסכול ועצבים וגם קצת מידע טכני תוך כדי 🙂

מיקרוסופט וסקייפ, מבט מעט שונה על הפרשה

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

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

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

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

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

העניין הוא שגם לסקייפ יש בסיס לקוחות מאוד גדול, שגם אותו מיקרוסופט רוצה לקבל. סקייפ זו לא רק תוכנת VoIP/IM אלא זה גם הרבה סוגי שירותים כדוגמת SIP Trunk ואפילו Calling Cards על סוגיהם. הם מספקים גישה לשירותי שיחות בהרבה מדינות בעולם ממקום אחד (התוכנה שלהם), ועוד מספר שירותים שונים שאתם מוזמנים לגלות בעצמכם. כל זה פותח למיקרוסופט (במידה והעסקה תאושר ונדע מה הם באמת מתכננים) עוד בסיס לקוחות עצום של שירותים עסקיים ופרטיים כאחד אשר מיקרוסופט יכולה אולי להרוויח כסף, ועוד לשים דריסת רגל במקום שאותו היא לא מבינה, ולמעשה נראה כיום שחיסול חברת Netscape היה יותר "פוקס" מאשר הבנה אמיתית של המתרחש.

העניין הוא שאף אחד לא יודע מה יקרה בשוק, ואי וודאות רע מאוד לבסיס לקוחות קיים, אשר הקהל אשר כן קורא ידיעות ומאמרים יחליט אולי להתרחק ולחפש תחליפים שונים לסקייפ, והמרוויחים מכך יהיו חברות אשר מספקות שירותי VoIP (או מפתחות כאלו – כמוני), וחברות אשר מוכרות Calling Cards (כרטיסי חיוג לעולם), אשר במידה ומיקרוסופט תפגע בגישה הנוכחית של סקייפ יעברו אליהם במקום.

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

מחלקה מופשטת

אחת התכונות שFPC 2.4.2 מביאה איתה הוא תמיכה ביצירת מחלקה שהיא abstract. כלומר אני יכול להגיד שמחלקה מסויימת היא בעצם סוג של API שכל מי שיורש ממנה צריך לממש בעצמו, אלא אם הוא גם class abstract משל עצמו.

הבעיה היא שהצוות של FPC לא המציא את הגישה אלא Embarcadero אחראים למחדל הזה – לפחות במימוש שלו.

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

כאשר אין לי צורך לרשת כלום, התחביר הוא עוד הגיוני:

TMyAbstractClass = class abstract

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

TMyInheritingAbstractClass = class abstract(TMyAbstractClass)

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

תבינו, ירושה רגילה נראת בצורה הזו:

TNormalInheritence = class(TMyInheritingAbstractClass)

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

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

2 טריקים לסיוע בעריכת קוד בלזרוס

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

לקפל קוד

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

בשביל זה המציאו את ה"פקודה" הבאה:

{%region}
...
{%endregion}

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

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

{%region /fold}

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

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

יחידת האב

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

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

{%MainUnit ../relative/path/unit_name.pas}

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

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

זה הכל להפעם, תכנות נעים 🙂

כשהקהילה יורה לעצמה ברגל III

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

אז הגיע הזמן לחלק השלישי בסדרה, הרי מ2007 עברו הרבה מאוד דברים…

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

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

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

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

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

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

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