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

מתודה דינמית ברובי

אם זה הולך כמו ברווז, זה נראה כמו ברווז ונשמע כמו ברווז, אולי זו שפת תכנות דינאמית 🙂

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

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

חזור שנית

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

אז איך אנחנו חוזרים על פעולה בתוך בלוק מסוייםב אותו המצב בו אנחנו נמצאים ?

#!/usr/bin/env ruby

companies = %w(Microsoft Apple HP DELL RedHat Mandriva)

companies.each do |name|
 print "Do you like the company #{name} (y/n) ? "
 yn = gets.chop
 unless yn.upcase =~ /^[ynYN]$/
   puts 'Please answer y or n.'
   redo # Here is the secret !!!
 end
end

המילה השמורה redo אומרת לרובי לחזור שוב פעם על הבלוק באיטרטור הנוכחי.

הפלט  שנקבל הוא כזה:

Do you like the company Microsoft (y/n) ? n
Do you like the company Apple (y/n) ? N
Do you like the company HP (y/n) ? n
Do you like the company DELL (y/n) ? y
Do you like the company RedHat (y/n) ?
Please answer y or n.
Do you like the company RedHat (y/n) ?
Please answer y or n.
Do you like the company RedHat (y/n) ?
Please answer y or n.
Do you like the company RedHat (y/n) ? n
Do you like the company Mandriva (y/n) ? Y

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

#!/usr/bin/env ruby

companies = %w(Microsoft Apple HP DELL RedHat Mandriva)

companies.each do |name|
 print "Do you like the company #{name} (y/n) ? "
 yn = gets.chop
 unless yn.upcase =~ /^[ynYN]$/
   puts 'Please answer y or n.'
   retry # Here is the secret !!!
 end
end

כאן השתמשנו במילה השמורה retry אשר מאפסת לנו את האיטרטור וגורמת לנו להתחיל ממש מההתחלה.

הפלט של הקוד הוא:

Do you like the company Microsoft (y/n) ? n
Do you like the company Apple (y/n) ? N
Do you like the company HP (y/n) ? n
Do you like the company DELL (y/n) ? y
Do you like the company RedHat (y/n) ?
Please answer y or n.
Do you like the company Microsoft (y/n) ? n
Do you like the company Apple (y/n) ? n
Do you like the company HP (y/n) ? n
Do you like the company DELL (y/n) ? Y
Do you like the company RedHat (y/n) ? y
Do you like the company Mandriva (y/n) ? y

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

כאשר אבל יש צורך לחזור רק על הפעולה האחרונה שבוצעה, אז השימוש ב redo נכנס לפעולה.

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

מפתחות זרים ללא מפתחות

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

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

כאשר צריך לפתח סביבה גרפית המשתמשת במפתחות זרים (או פשוט לייבא מידע מטבלה אחרת), אז TDataSet וכמו כן TDBLookupXXXXX נחלצים לעזרתנו ומספקים עבורינו את היכולת הזו ללא קשר אם יש לנו תמיכה ב foreign key או לא, וכאמור גם אם מדובר ב2 מסדי נתונים לגמרי שונים, למשל אחד SQL Server והשני PostgreSQL זה עדיין יעבוד.

לצורך ההדגמה, בואו נבנה באמצעות SQLite3 טבלאות:

DROP TABLE IF EXISTS "Authors";
CREATE TABLE Authors (ID AUTOINC_INT , Author VARCHAR(255));
DROP TABLE IF EXISTS "Comments";
CREATE TABLE Comments (ID AUTOINC_INT , Author INTEGER , Comment TEXT);

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

אז יצרנו 2 טבלאות:

  1. טבלת יוצרים
  2. טבלת הערות

עכשיו נבנה ממשק פשוט מאוד ל 3 חלונות: להמשיך לקרוא

בדיקות של אמות מידה למפרשי רובי

הספקתי לקרוא סוף כל סוף השבוע את אמות המידה (benchmark) של כמה מפרשים לשפת רובי.

בבדיקה השתמשו ב4 מפרשים:

  1. Rubinius
  2. JRuby
  3. Ruby 1.9 (גרסת הפיתוח לרובי 2)
  4. Ruby 1.8

כמו כן, היה שימוש בruby-benchmark-suite בשביל הבדיקות עצמם.

איכות מול מחיר

אחת הבעיות הקשות במדינת ישראל מבחינת עסקים היא שקהל העסקים חושב לטווח הקרוב מידי באמצעות הכיס בלבד ללא חזון של 5 ואפילו לפעמים 10 שנים קדימה (גם בתחום המדיני, את האמת ולא רק העסקי). יש בשוק החופשי בישראל הרבה עסקים אשר מעוניינים לשלם כל פעם מחדש 100 ש"ח על מכשיר מסויים 100 פעמים בגלל שהמכשיר מתקלקל וכבר אין אחריות, מאשר לקנות בפעם אחת מכשיר איכותי וטוב ב$200. אז כן, $200 קצת יותר יקר מ 100 ש"ח, אבל לקנות 100 פעמים את אותו מכשיר במקום פעם אחת, עולה הרבה יותר. למעשה 100 פעמים לקנות מחדש מכשיר מסויים שעולה 100 ש"ח יגרום לכם להשקיע 10,000 ש"ח סה"כ, בעוד ש$200 יגרום לכם להוציא (לפחות בזמן כתיבת פוסט זה) רק 760 ש"ח. אז אולי ההוצעה של ה10,000 ש"ח תהיה ב5 שנים, אבל תארו לכם שבמקום לשלם את הסכום הזה ב5 שנים, תשלמו רק 760 ש"ח פעם אחת ? יותר מזה, מה עם זמן העבודה שירד עד שתקבלו תחליף ? למעשה יש תשלום של למעלה מ10,000 ש"ח אחרי ה5 שנים במבט שהוא יותר ממוקד כאשר מחשיבים את הפגיעה בעבודה עצמה ואת המחיר של זה.

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

למשל כאשר אני מנסה למכור מרכזיות אסטריסק (העלות היא החומרה והעבודה שלי בלבד), אנשים לא רוצים לשלם הרבה כסף כי אפשר ללכת לחנות "רגילה" ולקנות מרכזייה באיזה 500-900 ש"ח במקום ב $1000. ההבדל הוא שהמרכזיות ב900 ש"ח אינן גמישות בכלל, ומותאמות למצב הנוכחי שלך בלבד. כל שינוי הכי קטן מהמצב הזה, והכסף שלך מתחיל לנזול בלי הפסקה, דבר שאצלי לא קורה. העסקים אינם חושבים קדימה כאשר מדובר במרכזייה, למרות שמרכזייה זה לא כלי שמחליפים אחת לחצי שנה, אלא כלי שאמור להיות שם לשנים, אז צריך לתכנן קדימה בקשר לגידול ולשינוי צורות עבודה (נגיד מחר מקימים call center של 5 אנשי מכירות דבר שלא היה לפני חצי שנה בכלל על הפרק, אבל יש צורך פתאומי לזה אחרי שהמנכ"ל ו3 משקיעים החליטו בכך ושכנעו את כל הוועד של החברה להקים את זה), מה קורה עם המרכזיות ה"זולות" האלו אז ? אז פתאום המרכזייה כבר לא מתאימה וצריך לקנות מרכזייה חדשה, רק הפעם במקום 900 ש"ח צריך לרכוש מרכזייה "זולה" ב$2000. אם היו משקיעים באסטריסק למשל, שמראש קצת יקרה יותר, ההשקעה היתה "חד פעמית" (למעט דברים ספציפיים). היות והמחיר הולך על חומרה אמינה וטובה, בעוד שהתוכנה מאפשרת לכם להתרחב עד שכמות הזיכרון RAM, מקום הדיסק הקשיח והמעבד של המרכזייה אינם מספיקים יותר לעבודה שלכם, אבל אם לקחתם אנשים כמוני, או עשיתם מחקר לבד ובחרתם בחומרה לטווח ארוך זה לא יקרה מאוד מהר.

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

ממשק פיתוח גרפי עבור ExtJS

במידה ואתם מפתחים תוכנות מבוססות Web, אז בטוח שנתקלתם באיזשהו שלב ב ExtJS, אשר נועדה להיות ספרייה המספקת תמיכה ברכיבים גרפיים ב DHTML DOM וכמובן איך אפשר בלי: AJAX.

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

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

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

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

את החבילה שאפשר להתקין לסביבת הפיתוח אפשר למצוא כאן.

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

פיתוח מהנה.

לטייל ברשת עם רובי

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

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

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

#!/usr/bin/env ruby

require 'rubygems'
require 'nokogiri'
require 'open-uri' # allow us to open a uri using the open command

html = Nokogiri::ׁHTML(open('https://idkn.wordpress.com'))
html.css('img').each do |img|
  puts img.attribute('src').value
end

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

בשורה הבאה אנחנו מאתחלים את המשתנה html כמחלקה של nokogiri. במקרה הזה עם התוכן של הדף הראשי של הבלוג הזה.

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

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

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

אם היינו רוצים לעבוד עם קובץ XML במקום (חשוב להבין ש nokogiri יודע להבדיל בניהם גם אם מאתחלים את ה html שלנו כ XML), אז נוכל לעבוד עם xpath במקום (דבר שאי אפשר לעשות עם HTML).

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

עיקרון ה 20 80 בקוד הפתוח

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

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

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

  • 80% צועקים
  • 20% מדברים

מתוך ה 20% המדברים אנחנו שוב מתחלקים:

  • 80% רק מדברים
  • 20% עושים בנוסף לדיבור

ובתוך ה20% יש עוד פעם את העיקרון הזה:

  • 80% – עושים אחת לתקופה
  • 20% – תורמים כדרך קבע

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

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

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

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

קצת סטטיסטיקות לגבי Firebird

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

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

בקשר לFlamerobin, הסביבה שהכי נפוצה בשבילו היא דווקא Windows

לזרוס משנה כיוון (ההתחלה)

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

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

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

את הpatch ותמונות מסך של השינוי אפשר למצוא בדיווח הבאג הבא.