הבלוג של ארתיום
בלוג על לינוקס, תוכנה חופשית, מוזיקה, סלסה, ומה לא!
מאמרים בנושא תכנה ומחשבים.
שוחררה גרסת בטא שניה של CppCMS
שוחררה גרסת בטא שניה של CppCMS. השינויים כוללים בין השאר:
- שיפורי ביצועים משמעותיים, בפרט בעבודה עם FastCGI, כך שהביצועים שלו לא נופלים מאלו של SCGI.
תיקוני באגים חשובים, ביניהם:
- תיקוני באגים בהעלאת קבצים
- בעיות שליחת תגובת HTTP במערכות אסינכרוניות.
- בעיות בייצוג מספרים ב־JSON.
התווספו דוגמאות נוספות, בפרט עבודה עם JSON ו־Comet.
אבל, אחד הדברים החשובים בעיניי בגרסה הזו, הוא לאו דווקא עצם שחרור הגרסה הנוספת, אלא מעבר הקהילה ישירות לגרסה 1.x.x של CppCMS בזכות שיפורים רבים שהוכנסו לתוכה, למעשה, רוב המשתמשים הפעילים ברשימת התפוצה של CppCMS משתמשים בגרסה החדשה, למרות שהיא עדיין נחשבת לגרסת בטא.
ואללה Vala!
כבר לא מזמן שמתי לב על פרויקט Vala של Gnome... אבל רק עכשיו יצא לי לנסות את הגרסה העדכנית שלו לעומק (גרסה 9.2).
כשקראתי בפעם הראשונה על Vala התגובה הייתה: "It is too good to be true".
- שפה מקומפלת ורצה בצורה טבעית (ללא זבל של VM ו־JIT) שזה אומר שהיא לא צורכת הרבה משאבי CPU.
- שפה שמשתמשת ב־GC פשוט (שימוש ב־reference counting במקום GC אמתי). מדוע זה טוב? כי יש לך דטרמיניסטיות ו־destructors - שזה אומר שהיא לא צורכת הרבה זיכרון.
- תמיכה ב־RAII שכל־כך חסר לי שפות כמו Java או C#.
ובנוסף לכל:
- הם הרוויחו ישירות SDK מאוד עשיר של Gnome. כי כל מה שמבוסס על GObject בא בצורה טבעית ל־Vala.
- הם הרוויחו תמיכה בפלטפורמות רבות בכלל שהם בחרו כשפת ביניים את C, כך שרוב העבודה הקשה הם משאירים למהדרי C (שיש בשפע החל מהדרים חזקים כמו gcc עד מהירים וקלילים כמו tcc).
לטעמי, שפה כמעט מושלמת לפיתוח יישומיים יומיומיים.
למעשה, היום ל־C++ יש מספר חלופות מצומצם שנותנות יכולות דומות עם פישוט של השפה עצמה: D, Vala, ו־FPC. (אני לא מדבר על Java או C#/Mono כי הם בכלל בליגה אחרת)
שפת D היא בעלת פוטנציאל גבוהה ביותר מכולם, אבל אני אישית חושב שעבודה עם Garbage Collection מקשה על הרבה דברים. היא מפרידה בין שני סוגי המשאבים: זיכרון וכל השאר (שהם הרבה יותר יקרים) כמו קבצים, נעילות, קשרי רשת פתוחים ועוד, שכן דורשים ניהול דטרמיניסטי. כך שאני חושב שעובדה עם Reference Counting נותנת מענה ל־95% מהמקרים, והשאר, נפתרים בקלות עם מעט תחכום.
Pascal בעייתית מהרבה בחינות, כולל ניהול משאבים ידני, העדר RAII וגם GC ועוד הרבה דברים שהופכים אותה מזדנבת מאחורי הטכנולוגיות המודרנית (עידו, זאת דעתי, אתה יכול להסכים או לא להסכים אתה).
עכשיו, על הנייר, נראה ש־Vala לקחה את הטוב ביותר מהרבה שפות
- מ־C היא לקחה ה־ABI הפשוט וקלות חיבור עם שפות אחרות, בסה"כ מדובר ב־C!
- מ־C++ היא לקחה את RAII, לקחה את ה־Destructors.
- מ־C# היא לקחה את OOP ואת הקלות של הכתיבה כך אפשר מהר ובקלות להיכנס לפיתוח.
אז החלטתי להסתכל לעומק
ציפו לי מספר אכזבות:
- Vala לא תומכת ב־Overloading בדיוק כמו ש־C לא תומך. ההיגיון מאחורי הוא די פשוט: הם רוצים שקוד C שנוצר יהיה שימושי גם מחוץ ל־Vala, קרי יישום של GTK יוכל להשתמש במחלקות שבמקור כתובות ב־Vala וזאת טענה מאוד חזקה שאני מוכן לקבל.
החריגות (Exceptions) ב־Vala הן ממש לא חריגות כפי שאנחנו מכירים אותם ב־C++ או ב־Java - הן לא מחלקות. אי אפשר ליצור היררכיה של חריגות, למשל DiskError שיורש מ־IOException והוא בתורו יכול יורש מ־Exception הבסיסי.
החריגות הן למעשה צירוף של תחום (domain) קוד ומחרוזת המייצגת את השגיאה, כך למשל כדי להציג חריגה שדיברנו עליה אנחנו מייצרים errordomain IOError בתוכו אנחנו בוחרים סוגים כמו
DISK_ERROR
שהוא פרמטר של החריגה, וכמובן גם טקסט. מבחינה זו, היה יותר נכון לקרוא להן Error Code מאשר חריגה במובן הקלסי.נכון שזה מכסה 95% מכל המקרים, אבל זה כן מייצר בעיה כשאתה רוצה להעביר מידה יותר מורכב (אם כי זה נדיר).
התיעוד עדיין לוקה בחסר הן מבחינת השפה עצמה והן מבחינת הספריות (אני צריך לפנות כל פעם לתיעוד GTK של C כדי להבין מה מתודה מסוימת עושה).
לפחות בשלב זה, אתה חייב לדעת C, כי לפעמים, כן קוראות שגיאות קומפילציה ברמת C, במיוחד עם ספריות חסרות או גרסאות לא תואמות.
אבל בגדול: שפה מהירה מאוד, פשוטה, בעלת SDK מאוד עשיר ואני צופה לה עתיד מעניין.
סיכום
היום Vala היא עדיין לא שפה מוכנה ל־Prime Time, אלא אם אתם מוכנים להיות בודקי הבטא שלה, מצד שני אם אתה יודע C ומכיר Gtk מספיק טוב, אתה תוכל להסתדר בקלות אתה.
היום מספר שפות יחסית מהירות ומתאימות לפיתוח יישומי Destkop: C, C++, D, C#, Java, Pascal ו־Vala. אני בהחלט רואה ב־Vala פוטנציאל גבוהה (כמובן לצידה של C++).
שוחררה גרסת בטא ראשונה של CppCMS 1.x.x
בשעה טובה, אחרי כשנה של פיתוח שוחררה גרסת בטא חדשה של CppCMS (הורדה), מעבר לשינויים מעמיקים ושכתוב מחצית מהקוד שהוסיפו תכונות מתקדמות רבות כמו תמיכה מובנית ב־Comet, היא מביאה את CppCMS לשלב תפיסתי אחר - בשלות פיתוחית.
כשהפרויקט התחיל, היה קשה מאוד להרים משהו עובד מבלי להיעזר בכמות עצומה של ספריות צד ג' ולהתחשב בנזק התחזוקתי והתפיסתי הן יגרמו לי בהמשך. אבל בלעדיהן לא הייתי מצליח להרים פרויקט כפישהו היום. אחרי ניסיון שצברתי יכולתי לשכתוב חצי מהמערכת כדי להגיע למצב בו היא נמצאת היום.
אז היום, הייתי מגדיר את CppCMS 1.x.x כגרסת תיקון גדולה לכל הטעויות התכנוניות שעשיתי בגרסאות הראשונות של CppCMS ושיפורים מהותיים שיכלו להיכנס לעקבות התיקונים האלה.
- הכנסתי event-loop מרכזי שמנהל את כל המערכת ומאפשר הרצת יישומי comet אסינכרוניים. דבר שדרש ממני להפתר מספריות כמו libfcgi ו־cgicc (וטוב שכך).
- בניתי מערכת שיודעת לשמור על ABI יציב בין הגרסאות
- העפתי את Boost שהופך תחזוקת ABI לסיוט מתמשך
- הוספתי תמיכה טבעית בפלטפורמות רבות בפרט ב־Windows ובקומפיילר MSVC.
ועוד, ועוד ועוד: רשימת השינויים העיקריים.
במילים אחרות... זאת בהחלט הגרסה המשמעותית ביותר מאז הבטא הראשונה של הפרויקט שוחררה.
יש עוד דרך ארוכה לגרסה יציבה, אבל אני מקווה שלקראת סוף 2010 תחילת 2011 היא תשוחרר.
קישורים
- הורדה
- הוראות בניה
- רשימת התיעוד המלאה (התיעוד עדיין חלקי)
- תיעוד מפורט - Doxygen.
על רישיון פרויקט תוכנה חופשית
אורון פלד פרסם מאמר שמסכם את הבעיות הגדולות של חברות שמפתחות תכנה קניינית. אכן, יש בעיות גדולות.
עם זאת, יש תכנה קניינית שמפותחת בחברה אחת יתרון אחד - כל זכויות היוצרים שייכות לה. יש הרבה מאוד פרויקטי תכנה־חופשית שלא מקפידים על ריכוז זכויות היוצרים בידי מפתח/ארגון יחיד. לדוגמה, פעם שלחתי טלאי לספריית SOCI, שהכיל כמה קבצים חדשים והתבקשתי לרשום באופן מפורש עליהם את הפרטים שלי כדי שיהיה ברור לי שייכים הזכויות. אני, ויתרתי על זכויות היוצרים שלי באופן מפורש לטובת הפרויקט, אפילו שלא התבקשתי לעשות כך.
למעשה, זאת תופעה נפוצה של פרויקטים גדולים, בהם זכויות היוצרים על חלקי קוד שונים שייכים הרבה מפתחים, לעתים אפילו כאלה שלא מעורבים בו או הקשר אתם אבד.
בד"כ זאת לא בעיה עד ש... רוצים לשנות את הרישיון. לדגומה, פרויקט תחת GPLv2 רוצה לשחרר קוד תחת GPLv3, או פרויקט תחת LGPL רוצה לעבור ל־MIT, Boost או BSD. מסתבר שזה לא אפשרי - כי כדי לשנות את הרישיון, אתה חייב לרוץ אחרי 50 מפתחים ולקבל מהם אישור לשינוי רישיון, לעתים זה לא אפשרי. אז או שאתה מוותר על שינוי רישיון או אתה מוותר על חלק מהקוד שלך, בדיוק מה שאורון פלד דיבר עליו.
רוצים דוגמה? OpenSSL ועוד כמה פרויקטים שתקועים של 4-clause-BSD שלא תואם GPL; גם אם הם היו מאוד רוצים לשנות את הרישיון, אי אפשר.
בקיצור. אני בהחלט מבין מדיניות חברות של Trollteck (לשעבר), MySQL (לשעבר) ועוד מספר לא מבוטל של חברות האחראיות לפיתוח תכנה חופשית שדורשות על ויתור זכויות היוצרים.
במילים אחרות... אם אתה מפתח תכנה חופשית, תחשוב טוב־טוב על הרישיון שלך והמדיניות שלך, במיוחד אם יותר ממפתח אחד עובד על הפרויקט.
הערה קטנה: יש מקרים בהם פיזור זכויות היוצרים הוא יתרון. דוגמה Linux, מכיוון שלאף אחד בפועל את זכויות היוצרים המלאות עליו, מובטח שהוא תמיד יישאר חופשי ולא תהיה חברה שתקנה עליו זכויות היוצרים הבלעדיים (כמו שקרה ל־MySQL), אפילו של־GPLv2 יש פריצות מסוימות שהגרסה השלישית פתרה אותם.
לשרוד פיתוח תואם "Windows" בעידן Unicode...
אם פיתחתם מעט עבור Windows אתם בוודאי מכירים את המושג שנקרא Wide-API. קרי לכל פונקציית המערכת יש שתי גרסאות: "ANSI" ו־"Wide", למשל: DeleteFileA ו־DeleteFileW, כאשר אחת מהן מקבלת char const *
והשניה wchar_t const *
.
נחמד לא? יש לך שני סוגי API שנוח לך, או לעבוד עם המחרוזות הפשוטות או לעבוד עם מחרוזות מבוססות "תווים־רחבים". אבל, לא בדיוק.
למעשה, לפי מדיניות של Microsoft, כדי לגשת לכל הכוח של מערכת ההפעלה אתה חייב להשתמש ב־Wide API אחרת... אתה אפילו לא תוכל ליצור קובץ "שלום.txt". נחמד, לא?
הבעיה שלא C99 ולא, C++, וגם לא C++0x לא מכירים במושג העמעום של wide-path ולמעשה, לפי התקן אין, דרך לפתוח קובץ שהשם לו הוא "שלום.txt" מקודד כמחרוזת של wchar_t
(רק char). כמובן חבר'ה ב־MS הם "ידידותיים" למפתחים והם הציע API חילופי: _wfopen(wchar_t const *,wchar_t const *);
וגם הוסיפו הרחבה לסטנדרט ב־Visual Studio: std::fstream::open(wchar_t const *,...);
הכל לטובת המפתח (הם כנראה לא שמעו בכלל על UTF-8)...
כאן, מתחיל הסיוט, למעשה למפתח יש שתי אופציות:
- להתעלם מהטמטום של Wide-API ולעבוד רק עם "ANSI-API" ו... התוכנה תפסיק לעבוד באופן אקראי על קבצים אקראיים, והמשתמשים המסכנים ישברו את הראש מה לא עובד.
- להתחיל לשכפל את כל הקוד שלך למקרה wide ולמקרה נורמלי.
סיוט. לא פלא, שרבים בורחים באופציה הראשונה, ולכן בשנת 2010, אנחנו נתקלים יישומים כמו Thunderbird, שלא עובד כשתיקיית המשתמש שלך בחלונות מכילה תוים עבריים.
כך גם, אני כשהתחלתי תמיכה בחלונות ב־CppCMS החלטתי להתעלם מהעובדה ש־fopen
או std::fstream::open
לא יעבדו לי. אבל בסוף ייסורי מצפון הזיזו את כף־המאזניים: מספיק לכתוב קוד גרוע... והכנתי ספריית עזר קטנה, קראתי לה booster::nowide. כל מה שהיא עושה זה: להעביר ל־namespace שלך את הכלים סטנדרטיים שקיימים ב־stdio וב־STL בכל מערכות ההפעלה נורמליות. ובחלונות, היא פשוט עוטפת אתה API _w*
עם פונקציות משלה שממירות UTF-8 ל־UTF-16 ואז קוראות לפונקציות המתאימות.
בנוסף יצרתי מחלקות תואמות ל־std::fstream שעובדות מעל stdio (ועל הדרך סוף־סוף הבנתי כיצד לממש streambuf משלך).
התוצאה? אם אתה מתכוון לתמוך בחלונו, במקום לכתוב
std::ofstream f("שלום.txt")
שמייצרת ג'יבריש במקרה הטוב אתה כותב:
booster::nowide::ofstream f("שלום.txt")
וזה עובד בצורה שקופה, כנ"ל, std::fopen, std::freopen, std::remove, std::rename - רק החלף std::
ב־booster::nowide::
.
במילים אחרות: no-more-wide-crap!
הספרייה היא חלק מ־booster של CppCMS ומופצת תחת רישיון Boost (משהו סגנון MIT). אם מישהו ירצה ספריה בלתי תלויה ב־booster, אז תגידו ואני אגזור אחת (לא מסובך בכלל).
קריאה נוספת: "Should UTF-16 be considered harmful?"
גרסת הספרית nowide התלויה בקומפיילר C++ לבלבד ניתנת להורדה כאן:
http://art-blog.no-ip.info/files/nowide.zip