ארכיון חודשי: ספטמבר 2010

הדואר האדום

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

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

== Contributing
Please do!  Contributing is easy in Mail:
1. Check the Reference RFCs, they are in the References directory, so no excuses. להמשיך לקרוא

עט קנייני

"העט חזקה מהחרב"

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

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

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

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

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

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

ריקוד המכונה

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

למשל בעולם האינטל/AMD יש לנו חיים מאוד קלים. אנחנו עובדים עם אינדיאנים קטנים (Little Endian). מי שמתעסק במעבדי ARM, עדיין עם חיים קלים, אינדיאנים קטנים והוראות מעבד ממש דומות, אבל לא זהות. ההתעסקות עם המעבד המתמטי של ARM ועוד כמה הוראות שונות לגמרי מאשר מעבדי Intel.

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

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

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

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

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

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

ההקדמה מאוד הזכירה לי את השיר של משינה בשם ריקוד המכונה, שהוא בעצם חיקוי (כמו כמעט כל השירים של הלקה) של השיר של madness בשם One Step Beyond.

ניתובים דינאמיים עם סינטרה

אם אתם עדיין לא מכירים את סינטרה, אז דבר ראשון תתבישו לכם, ודבר שני איפה אתם חיים ? זה הmicro-framework המדובר ביותר בשנתיים האחרונות, ויש כל כך הרבה ניסיונות לממש אותו בעוד שפות, אבל הוא פשוט תפור על רובי כמו כפפה ליד.

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

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

Byte Marks

BOM הוא קיצור ל Byte Order Mark, אשר מתלבש בד"כ על קבצי טקסט בהתחלה שלהם, ואם לא יודעים לטפל בו הוא עושה שמות במה שעשינו, אבל כאשר יודעים לטפל בו, הוא מסביר לנו מה הקידוד של הטקסט בקובץ והסדר שלו, במידה ויש הבדל בין אינדיאנים גדולים וקטנים.

אז למה הוא עושה שמות במה שעשינו ? ובכן זה אוסף של בין 2 ל4 תווים אשר בייחד מסבירים מה הקידוד, אם זה UTF-8, UTF-16, UTF32 וכו'. כאשר UTF-16 ו32 יכולים להיות ב2 סוגי אינדיאנים והסימני בתים בעצם מסבירים מול מה אנחנו מתמודדים. כאשר יש צורך לעבוד עם UTF-7 (לא באמת חלק מהחבורה של UTF-8, אלא אח חורג), אז ההתנהגות של BOM קצת שונה והוא יכול להגיע עם עוד בית נוסף (עזבו, אל תכנסו לכאב ראש הזה של UTF-7, אלא אם אין ברירה).

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

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

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

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

המדריך הלא (רחוק מלהיות) מושלם ליצירת gem ברובי

קובץ gem הוא בעצם קובץ tar המכיל בתוכו עוד כמה קבצים המתארים איך ומה לעשות בשביל להתקין ספריות עבור שפת רובי (בעיקר).  gem הוא בעצם סוג של חבילת התקנה ממש כמו מנהל החבילות הקרובות להפצתכם (בלינוקס וFreeBSD בעיקר).

gem בניגוד למרבית מנהלי החבילות האחרות, יודע גם להתמודד עם כמה גרסאות של אותה חבילה, ולטעון רק את זו שאנחנו רוצים. כך שאם יש לנו 4 גרסאות של אותה ספרייה, וקוד legacy שמשתמש בגרסה 1.0 מול קוד חדש אשר משתמש בגרסה 8.4, אז שניהם ניתנים להתקנה ולשימוש באותו הזמן, שזה יתרון מאוד גדול מצד אחד, אבל מצד שני זה כאב ראש לא קטן אם לא נותנים על כך את הדעת ולא יודעים להתמודד עם הנושא, היות ואם אנחנו זקוקים לגרסה 8.4 אבל טענו את גרסה 1.99 אשר היא גרסת מעבר לגרסה 2, אז אולי הדברים לא יתפקדו כמו שרצינו. וזה יקרה אם נשאיר ליד הגורל לבחור עבורינו את הגרסה הרצויה.

אז נגיד ויש לנו ספרייה מגניבה בשם IK Utils (קצת נרקסיסטי אני יודע), שכל מה שהיא עושה זה צליל של ping (רגע זה בכלל קשור לשפה אחרת…), ואנחנו רוצים לתת לה אריזה יפה שיהיה אפשר להתקין אותה באמצעות ruby gem. אז בשביל זה אנחנו צריכים ליצור קובץ, נגיד ניתן לו את השם ik_utils.gemspec (הסיומת מאוד רצויה, אבל לא חובה) וכתוב בה את הקוד הבא:

Gem::Specification.new do |s|
  s.name = %q{ik-utils}
  s.version = "0.1"
  s.date = %q{2010-09-14}
  s.authors = ["Ido.K."]
  s.email = %q{idok at something something something ...}
  s.summary = %q{This is an util that does ping}
  s.homepage = %q{http://ik.homelinux.org/}
  s.description = %q{This is an util that does ping when the administration enters the room, and it's the most expensive util at the room}
  s.files = ['LICENSE', 'doc/ping.html', 'README', 'exampels/ping.rb', 'test/ping.features', 'test/ping.rb', 'lib/ik/utils/ping.rb']
end

ועכשיו מה שאנחנו צריכים זה ליצור gem (אחרי שדאגנו שכל הקבצים נמצאים באותה הספרייה של קובץ ה gemspec) על ידי השורה הבאה:

$ gem build ik_utils.gemspec

וזהו יש לנו gem פשוט וקל.

כללים למשלוח דואר אלקטרוני

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

דואר זבל להמשיך לקרוא

HTTY

HTTY הוא רעיון מאוד נחמד שכתוב ברובי. הרעיון הוא לאפשר לסייר בכתובת HTTP בפרוטוקולים השונים של GET, POST, HEAD, PUT, OPTIONS, TRACE ו DELETE, ובעצם לעשות מניפולציות על המידע ולקבל בשורת הפקודה את ההתנהגות הרצויה בהתאם. הכל נעשה תחת המסוף שקרוב למקום מגורינו, כלומר זה בעצם HTTP עם TTY בייחד, אשר מתנהג כסוג של shell כמו bash.

הרעיון של הפרוייקט הוא לקבל את הכוח של curl ו lynx בייחד ומכיל את התכונות הבאות:

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

עם התכונות האלו, אפשר בעצם לעשות את האפשרויות הבאות:

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

בנוסף לכל זה, יש כמובן API מוכן לשימוש ברובי לשימוש במערכת.

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

הצד האפל של הקוד – או רק בגלל שאתה יכול זה לא אומר שאתה צריך …

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

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

הנה קוד מתוך מימוש של ווקטור שקראתי השבוע, האם לדעתם הקוד הזה קריא ? להמשיך לקרוא

25 דקות של משימה

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

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

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

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

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

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

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