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

טיפ שני ב Firebird

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

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

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

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

אז לשם שינוי השם, אנחנו נשתמש ב 2 השאילתות הבאות:

UPDATE RDB$RELATIONS
SET RDB$RELATION_NAME='NEWNAME'
WHERE RDB$RELATION_NAME='OLDNAME';
COMMIT;

UPDATE RDB$RELATION_FIELDS
SET RDB$RELATION_NAME='NEWNAME'
WHERE RDB$RELATION_NAME='OLDNAME' and RDB$SYSTEM_FLAG=0;
COMMIT;

הטבלה הראשונה באמת אחראית על שם הטבלה ואנחנו משנים את הערך שלה מהשם הישן לשם החדש. ה commit הראשון נועד להבטיח שהשינוי יכנס לתוקף מיידי.

הטבלה השנייה היא שיוך השדות לטבלה ששינינו לה את השם. כן, השם של הטבלה והשדות נשמרים בצורה שטוחה לגמרי ב Firebird.

חשוב לדעת שאם השתמשנו בשאילתאות, stored procedure, triggers, view וכו' עם הטבלה הישנה, צריך לשנות גם שם את השם לטבלה החדשה, וזה כבר יכול להשתנות ידנית, ממש כמו בשאר מסדי הנתונים שאני מכיר לפחות.

בדיקת תקינות Javascript/EmcaScript

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

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

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

טיפים ב Firebird חלק ראשון

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

select first skip

במידה וצריך להחזיר את ה10 רשומות הראשונות, אפשר להשתמש ב מילה השמורה של first בצורה הבאה:

select first 10 * from table;

ונקבל את ה10 רשומות ראשונות

במידה ונרצה להחזיר רק מהרשומה הרביעית, נשתמש ב select skip:

select skip  3 * from table;

ונקבל את הרשומה הרביעית ומעלה.

ניתן גם לשלב בין first לבין skip:

select first 10 skip 3 * from table;

ונקבל את 10 הרשומות הראשונות מהרשומה הרביעית ועד לרשומה ה13

להעלות את Ruby on Rails על סולם

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

Gregg Pollack מ new relic יצר 14 screen cast (אני מחפש מילה בעברית שתסביר טוב מה זה) על איך לגרום לrails לעלות בסולם השימוש, או scale בלשון העם.

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

את ה video cast אפשר למצוא כאן.

גישה טכנולוגית

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

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

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

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

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

עבודה עם מחרוזת מרובת בתים ברובי

במידה שאתם צריכים לעבוד עם תווי multi-byte  כדוגמת עברית ב UTF-8, בברירת מחדל רובי לא יודע לזהות שזו כוונתכם.

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

$ gem install unicode

ועכשיו בקוד יש להוסיף את 2 השורות הבאות:

require 'unicode'
$KCODE = 'UTF-8'

ועכשיו אם נרצה לעבור על תווים שהם utf-8, נוכל לעשות זאת ללא בעיה:

'שלום עולם'.each_char do |ch|
puts ch
end
ש
ל
ו
ם

ע
ו
ל
ם

ועכשיו אפשר לדעת שהמחרוזת יודעת לזהות מחרוזת מרובת תווים.

חשוב לדעת שהמודול אינו מושלם ואינו תומך בצורה מלאה בכל המתודות של String.

מלפפון עברי

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

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

עכשיו רק צריך להתרגל לכתוב בדיקות וכבר אין תירוצים 🙂

lambda ללא λ

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

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

בואו נכתוב פונקציה מאוד פשוטה:

function ReturnSomething : integer;
var
X : integer;

procedure print_double_X;
begin
writeln(X * 2);
end;

begin
X := 2;
print_double_X; { print 4 }
end;

כמו שאפשר לראות, יש לי תמיכה ב nested functions בפסקל ואם אני כותב משתנים לפני ההגדרה, אז אפשר גם לגשת אליהם דרך אותן פונקציות, מה שבעצם גורם למצב שמתנהג כמעט לגמרי זהה ל lambda. כמובן שתלוי עד כמה "גבוהה" רוצים להגיע כאשר מדברים על lambda, אבל אני יכול ליצור עכשיו בתוך nested function עוד nested function וכו' וככה להשיג הרבה אפקטים זהים כמעט ב100%.

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

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

צעדים ראשונים בתכנות מבוסס בדיקות

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

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

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

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

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

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

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

BucketWise – תוכנה לניהול מידע פיננסי אישי

BucketWise היא תוכנת קוד פתוח מבוססת web שנכתבה ב Ruby On Rails, ותפקידה הוא לספק ניהול אישי (לא עסקי) של כל המידע הפיננסי של המשתמשים בה.  התוכנה מאפשרת ניהול משתמשים שונים במערכת וכן ריבוי חשבונות לכל משתמש.

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

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

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

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

בשביל להתקין את תלויות התוכנה נוכל להשתמש ב gem של רובי (אלא אם יש לנו חבילות קיימות בהפצה שבה אנחנו משתמשים) בצורה הבאה:

$ sudo gem install <package name>

כך שאת התלויות הבאות נוכל להתקין בצורה הבאה:

$ sudo gem install capistrano rake rails highline sqlite3-ruby

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

אפשר לראות כאן ו כאן איך לעבוד עם התוכנה.