הבלוג של ארתיום
בלוג על לינוקס, תוכנה חופשית, מוזיקה, סלסה, ומה לא!
מאמרים בנושא Boost.
מחשבות על Boost.
ספריית Boost היא אחת הספריות הגדולות של C++ הן מבחינת הגודל הפיזי והיקף הספריות והן מבחינת המרכיבים החשובים שהיא מספקת.
Boost ל־C++ היא היום אחת הספריות הנחוצות ביותר הכללת בין היתר: טיפול בחוטים, ביטויים רגולריים, סינגנלים, סוקטים ועוד עשרות מודולים חשובים ושימושיים; ומה שעוד יותר חשוב הם בנויים בצורה טובה, הגיונית ודי איכותית.
למעשה, המתכנת C++ המודרני שהתרגל לנוחות ש־Boost מספקת יתקשה לכתוב בלעדיה את הקוד.
כמובן שהיא לא הספרייה היחידה, גם כלים כמו Qt, GTKmm ואחרים מספקים כלים בהיקף דומה... אבל ל־Boost יש יתרון גדול: חלק מהכלים שקיימים היום ב־Boost כבר עברו כפי-שהם ל־STL החדש. למעשה, יש ערך מוסף לעבודה עם Boost: אם אתה רגיל לעבוד עם boost:function, boost::bind, boost::regex, boost::thread אתה תמצא את עצמך יום אחד משתמש ב־std::function, std::bind בצורה שקופה לחלוטין בלי תלות בספריית צד ג'.
אבל מה? בניגוד לספריית STL שבאה עם קומפיילר ומבטיחה לך תאימות לאחור ואפשרת לא לדאוג ומגרסאות... Boost היא לא כזו:
- כל מספר חודשים יוצאת גרסה חדשה שלא תואמת לקודמת!
- אתה יכול לצפות שאיזושהי גרסת Boost תסופק עם הפצת לינוקס, אבל אתה לא יודע איזו?
למעשה, לצורך עבודה באוניברסיטה הייתי צריך לכתוב תכנה שעובדת עם ביטויים רגולריים, עם חוטים, עם טעינה ושמירה של תמונות.
התכנה הייתה בשתי גרסאות (עם ifdefים): כזו שהשתמשה ב־Qt4 בלבד (וסיפקה GUI), וכזו שהשתמשה ב־Boost ולא סיפקה GUI.
היה לי קל מאוד לקמפל את התכנה שעבדה עם GUI ולשלוח למישהו אחר לבדיקה, כי לא היה לי אכפת איזו גרסת Qt4 מותקנת אצלו, כל עוד היא מספיק חדשה!
עם Boost לא היה שום סיכוי לעשות דבר כזה... הייתי צריך או לקמפל סטטית הכל, או לקמפל בדיוק עבור הגרסה שמותקנת אצל אותו האדם.
Boost היא ספרייה נהדרת. אבל, היא גורמת לי להתרחק ממנה יותר ויותר - כי יש פרויקטים שהיא פשוט לא רלוונטית עבורם בגלל שהיא שוברת API/ABI לעתים קרובות.
תכירו Boost.Locale
אחרי תהיות עמוקות על תמיכה בלוקליזציה ב־C++, הבנתי שלא ניתן יהיה ללכת איתה רחוק. לקחתי ICU והתחלתי לעטוף אותו בסביבה ידידותית לתכנות C++ מודרני.
אחרי הרבה עבודה הבנתי... כל מה שאני עושה יהיה שימושי הרבה מעבר ל־CppCMS ולכן החלטתי להכין ספריה נפרדת שמטפלת בלוקליזציה במטרה לשלב אותה ב־Boost. כך נולד Boost.Locale שנותנת כלים פשוטים וחזקים לעבודה עם לוקליזציה.
דוגמה פשוטה שתבהיר את החשיבותה ועוצמתה. הנה קטע קוד שמציג למשל את תאריך המאמר באתר:
out << format(translate("{1}, posted at {2,date} on {2,time} by {3}"))
% title % date % author;
ועכשיו המתרגם יכול לתרגם את המשפט לצורה הבאה:
"{1}, פורסם ב{2,locale=he_IL@calendar=hebrew,date} (לועזי {2,date}) ב־{2,time} ע"י {3}"
מה קרה כאן? התצוגה באנגלית תהיה
Some article was published at 11/8/2009 on 10:30 PM by somebody
כאשר התצוגה בעברית תהיה
מאמר מסוים פורסם בכ"א בחשון התש"ע (לועזי 08/11/2009) ב־22:30 ע"י מישהו
למעשה, בלי שימוש ב־libhdate, בלי לעבוד קשה מידי, קיבלתי אפשרות להציג את התאריך העברי והלועזי לפי הלוקל העברי, רק בגלל ש־ICU תומך בלוח־השנה העברי.
למעשה, עבזרת Boost.Locale ניתן לעשות המון דברים בצורה פשוטה. למשל:
cout << as::spellout << 123 <<endl;
יידפיס בלוקל עברי
מאה עשרים ושלוש
יאפשר לחלק מילה "שָלוֹם" לארבעה תווים בהתחשב בניקוד: "שָ", "ל", "וֹ" ו־"ם" ועוד. למיין טקסט בצורה נכונה ועוד עשרות פעולות חשובות שניתנות ע"י ICU רק בצורה נוחה וטבעית ל־C++.
תכירו Boost.Locale:
- תיעוד מלא: http://cppcms.sourceforge.net/boost_locale/html/index.html
- מדריך: http://cppcms.sourceforge.net/boost_locale/html/tutorial.html
- הורדה: https://sourceforge.net/projects/cppcms/files/
תהנו, אשמח גם לתגובות.
תסריט פיתון להחלפת namespace של Boost.
הכנתי תסריט קטן שמאפשר שינוי גורף של Namespace עץ הקוד של Boost ל־Namespace חילופי כדי למנוע התנגשות בין גרסאות Boost שונות: http://art-blog.no-ip.info/files/rename.py.
הרצה: ./rename.py /path/to/boost/tree new_namespace_name
עכשיו כל ה־defineים וכל הסימבולים יימצא ב־namespace אחר ואפשר יהיה לבנות רכיבים ללא תלות בגרסת Boost.
הערות:
- השימוש על אחריותכם, גם אם זה יאכל לכם את החתול או יהרוס את כל הקוד במחשב שלכם.
- הוא עדיין די ראשוני, אבל הצלחתי לקמפל רוב הספריות החשובות ולהריץ כמה regression tests.
את התסריט כתבתי לפתרון אפשרי לבעיה שהצגתי במאמר הקודם
פיתוח יישומי רשת ב־C++ או הצצה ל־Boost.Asio.
במאמר זה, אביא סקירה קצרה של ספריית Boost.Asio -- ספרייה לפיתוח יישומי תקשורת ב־C++ בצורה מהירה, יעילה ונוחה. ההכרות שלי איתה התחילה, דווקא מצורכי העבודה. אחרי זמן קצת, הבנתי שהיא מאוד נוחה ואפילו תהיה שימושית עבור CppCMS. למעשה, הספרייה הזו, אפשרה לי לעטוף את ספריית ה־cache של CppCMS ולהפוך אותה למבוזרת --- לבנות פתרון בסגנון memcached --- תוך מספר שעות בלבד.
הספרייה הזו קיימת בשתי גרסאות:
- גרסת Boost.Asio: היא חלק מ־Boost החל מגרסתו 1.35.
- גרסת Asio עצמאית, שדורשת Boost גרסה 1.33 ומעלה --- מאפשרת לעשות שדרוג של ספרייה ללא תלות בגרסת Boost.
אחד המאפיינים המעניינים שלה היא העובדה, שהספרייה כולה כתובה על בסיס Template Metaprogramming ומהווה אוסף קובצי־".hpp" בלבד.
"בעיית עשרת אלפים קשרים" או "למה צריך ספריות כאלה בכלל?"
מעבר לעובדה ש־Berkeley Sockets API די מסובך, עדין ושונה במערכות הפעלה שונות --- כבר סיבה מספיק טובה לבנות מעטפת עבורו --- אני אתרכז דווקא במשהו אחר, כתיבת יישומים יעילים.
נתחיל מסיפור קצר. נגיד אתם רוצים לפתח שרת מסרים מידיים שמטפל במספר רב של הלקוחות בו זמנית. בסה"כ השרת מבצע תפקיד מאוד פשוט: קבל הודעה מלקוח מסוים, להעביר ללקוח אחר.
יש מספר גישות לבניית השרת:
המשך...על C++0x ועל TR1.
מה זה C++0x ו־TR1? הם השינויים בסטנדרט החדש של C++, כאשר C++0x מדבר בעיקר על שינויים בשפה, ביניהם: הוספת פונקציות למדא , טיפוס auto ורבים אחרים. הסטנדרט החדש מגדיר גם שינויים בספריית C++, הנקראים TR1.
היום, gcc מתקדם לאט־לאט ביישום של שינויים בליבה של השפה, אבל מה שיותר מעניין אותנו כרגע, זה שרוב השינויים המוצעים ב־TR1 כבר נכנסו לספריה סטנדרטית (כרגע תחת namespace: tr1). ביניהם: מצביעים חכמים, "אובייקט הפונקציה" או Deligators במונחי C#, טבלאות hash, ביטויים רגולריים ועוד.
חלק מהשינויים זמינים כבר בגרסה 4.1 של gcc, אחרים (כמו ביטויים רגולריים) זמינים כבר ב־gcc 4.3. חלק גדול מהשינויים האלה נלקח כפישהו מספריות Boost.
נעבור בקצרה על האופציות החדשות:
המשך...