ארכיון חודשי: ינואר 2013

לימוד רובי – הדרך להארה

"In Ruby, just like in real life, our world is filled with objects. Everything is an object – integers, characters, text, arrays – everything." — Ruby monk

ישנו אתר מאוד מעניין הנקרא ruby monk אשר מאפשר דרך לימוד אינטרקטיבית עבור שפת התכנות רובי (בטח לא ניחשתם את זה … 🙂 )

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

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

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

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

שימוש ב DATA של רובי

רובי מאפשרת ליצור איזור מיוחד בסוף קובץ ריצה.

האיזור נקרא __END__ והוא מאפשר לשים טקסט חופשי שם, בלי שהוא ישפיע על הקוד (אלא אם הוא קידוד שפה שונה משאר המידע בקובץ).

אפשר אבל מהקוד עצמו לקרוא את המידע הזה, ולעשות עליו פעולות:

#!/usr/bin/env/ruby
#

DATA.each_line do |l|
  puts l
end

__END__
hello
world

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

והנה דרך להציג את התוכנית הקודמת בתצורה אוקטאלית (מבוסס על הקוד מכאן):

#!/usr/bin/env ruby
#

if __FILE__ == $0
  offset = 0
  while (buf = DATA.read(16)) do
    bytes = buf.unpack 'C*'
    puts "%08X: %s\n" % [ offset, bytes.map { |b| " %04o" % b }.join('') ]
    offset += 16
  end
end

__END__
0000000 2123 752f 7273 622f 6e69 652f 766e 7220
0000020 6275 0a79 0a23 440a 5441 2e41 6165 6863
0000040 6c5f 6e69 2065 6f64 7c20 7c6c 200a 7020
0000060 7475 2073 0a6c 6e65 0a64 5f0a 455f 444e
0000100 5f5f 680a 6c65 6f6c 770a 726f 646c 000a
0000117

50 שנים של הדוקטור – או למה DRM ומניעת שימוש פוגעים גם ברשתות ההפצה

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

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

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

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

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

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

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

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

מוקדש כחומר למחשבה

Some IX2-200 hacking

I've bought an Iomega IX2-200 NAS as a backup solution. For it's price, it was the best choice imho (but there are much better solutions out there, but a lot more expensive).

It runs Linux (Debian to be exact), but on default it does not enable ssh, and you can choose only sftp or rsync (as a client), but not at the same time.nas_diagnostics_page

Older firmware can open the ssh part as described at the link, however here is how to do it for a newer firmware:

  1. Enter your device
  2. Login
  3. Go to the following address:
    http(s)://<IP ADDRESS>/diagnostics.html
  4. Enable ssh (it might require you to change port due to proftpd acting as sftp server and binded on port 22)
  5. Use the user root with your login password, but provide a prefix of "soho" prior to it. That is, if your password is "1234" (and I hope it is not), then do the following to your password:
    soho1234
  6. Enjoy the access, and remember: "With great power, comes great responsibility" (or something like that)

For my next post, I'll understand how to make it work as an rsync server.

Remember the joy of device hacking 🙂

let's go

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

אז הקדשתי שעה (פלוס) להבין קצת יותר לעומק את השפה.

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

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

הנה משהו אחד כזה – משפט if אשר מאוד בעייתי בעיני:

if a := UserAge(); a < 12 {
 ...
}

ניתן (במידה ורוצים) להציב ולבצע מספר פעולות במשפט הif. ד"א לא ניתן לשים סוגריים ל if.

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

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

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

לחרדת הקורא צפריר, go מהודרת סטטית לelf (בלינוקס) את קבצי הריצה שלה (אלא אם משתמשים ב gccgo), מה שאומר שהם יכולים לרוץ על כל מערכת המתאימה להם. כלומר גם אם קימפלתם אותם על debian stable, תוכלו להריץ אותם על arch ללא צורך למקפל מחדש.
ואם זה לא מספיק להחריד את צפריר, אז יש לשפה גם מנהל חבילות משל עצמה במקום לסמוך על הפצה כזו או אחרת …

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

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

בדיקות אוטומטיות אינן התשובות להכל

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

לאחרונה היה באג בספרייה בשם ActiveRecord, אשר במצב מאוד מיוחד, היה ניתן לגרום למתודה find_by_‎ לבצע SQL Injection. הבאג ד"א היה ניתן לניצול רק במצבים מאוד מדוייקים של שימוש במתודות, ולכן אם לא היה שימוש בגישה מסויימת, לא היה ניתן לנצל אותם, אבל הבאג היה עדיין קיים, והמליצו לכולם לשדרג לתיקון הבעיה.

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

כלומר מרבית השימושים בActiveRecord מעולם לא היו גורמים לבעיות או מסכנים אתר מסויים ב SQLi. ועכשיו נשאלת השאלה: האם TDD מסוגל לעלות על מקרה קצה כל כך קיצוני ?

האם ב99.9 אחוז מהבדיקות שתעשה הבדיקה תצא תקינה, האם תדע לכתוב את הבדיקה 0.1 בה תצליח לגלות באג ?

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

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

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

מיקרוסופט ו PC – סוף עידן (?)

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

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

ms-surface - windows 8אני חייב לציין כי למעט מספר בעיות קטנות יחסית, כאשר מתעסקים עם Microsoft Surface בחומרה שאליה החברה כיוונה, המערכת מתפקדת מצויין ונוחה מאוד (כאמור למעט בעיות קטנות).

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

deadlock טכנולוגי

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

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

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

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

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

להמשיך לקרוא

gbak ויכולותיו

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

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

יש לה הרבה יכולות כדוגמת:

  • המרה בין סביבה לסביבה (למשל Little/Big Endian,‏ 32 מול 64 ביט וכו)
  • דחיסת מידע וניקוי המידע שנשמר ממחיקות (למשל)
  • שינוי פעולות אבטחה, כדוגמת שינוי משתמש ו/או סיסמה למסד הנתונים
  • גיבוי למספר קבצים קטנים את המידע של מסד הנתונים
  • שדרוג בין גרסאות של השרת, ובכך להמיר דברים לפי הצורך

ועוד פעולות נוספות, כדוגמת שחזור אותו המידע 🙂

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

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

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

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

IPC באמצעות Redis ורובי

Redis הוא מסד נתונים אשר אינו מבוסס SQL וכתבתי עליו רבות כאן בעבר.

לאחרונה נדרשתי לפרק מערכת שלי למספר תתי מערכות, ולהעביר מידע בניהם. כמובן שיש הרבה מאוד דרכים לעשות זאת, כדוגמת Message Queue ‏(RabitMQ, ZeroMQ וכו'), עבודה עם PIPES ביוניקס, עבודה בתצורת client server ועוד הרבה מאוד דרכים כיד הדמיון והמערכת הטובה לכם. אני החלטתי ללכת על Redis.

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

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

לRedis יש מספר דרכים לשלוח ולקבל אירועים, אבל אני הולך לדבר כאן על Publish ו PSubscribe. האחרון מאפשר להאזין להודעות באמצעות תבנית חיפוש (עם כוכביות), במקום שם מלא ומדוייק שאחיו Subscribe מספק.

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

שליחת הודעות מאוד פשוטה:

require 'rubygems'
require 'redis'

redis = Redis.new(:host => 'localhost')

10.times do |i|
  redis.publish("number_#{i + 1}", Marshal.dump({:number => i}))
  sleep( (i + 1) / 10.0)
end

התחברתי לRedis, והתחלתי לרוץ על כל המספרים מ0 ועד 9.
יצרתי מפתח שההתחלה שלו הוא number_‎ ולאחר מכן המספר. המבנה חשוב מאוד בשביל להצליח להאזין לאירוע.
לאחר מכן, יצרתי תצורה בינארית עבור Ruby Hash ושלחתי אותה כמידע שאני זקוק לו לשימוש.
כאשר הפעולה מסתיימת, אני נח כמות של מילישניות לפי המספר, החישוב לדעתי די ברור כאן.

הפרוסס השני צריך להקשיב לאירוע:

require 'rubygems'
require 'redis
redis = Redis.new(:host => 'localhost')

redis.psubscribe('number_*') do |on|
  on.pmessage do |pattern, event, message|
    puts "pattern: #{pattern}, event: #{event}, message: #{Marshal.load(message)}"
  end
end

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

התוצר כאן יהיה בסגנון הבא:

pattern: number_*, event: number_1, message: {:number=>0}
pattern: number_*, event: number_2, message: {:number=>1}
pattern: number_*, event: number_3, message: {:number=>2}
pattern: number_*, event: number_4, message: {:number=>3}
pattern: number_*, event: number_5, message: {:number=>4}
pattern: number_*, event: number_6, message: {:number=>5}
pattern: number_*, event: number_7, message: {:number=>6}
pattern: number_*, event: number_8, message: {:number=>7}
pattern: number_*, event: number_9, message: {:number=>8}
pattern: number_*, event: number_10, message: {:number=>9}

מי תיקח כמתכנת אצלך ?

במהלך 2012 השתתפתי במספר דיונים ואף יעצתי למספר חברות בדבר עובדים המתאימים לתפקידים כאלו ואחרים בעולם התכנות.

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

בהרבה פורומים אני רואה את התשובה: "שפות התכנות הנפוצות הן 1,2,3,4 אז תלמד אותן". זו הטעות הכי גדולה לדעתי להגיד למישהו לעשות. היות ומה שנכון כרגע לא בהכרח נכון עוד שנתיים מהיום.
כן ללמוד גם את השפות 1,2,3,4 . הבעיה היא שזה לא "בשלוף", כי צריך להבין mindset של שפה, יותר מאשר את התחביר שלה, וזו כבר פעולה שלוקחת זמן.

אז מה כן אני מייעץ ?

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

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

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

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

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

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

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

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

התוסף הראשון שלי חלק ראשון

שנה חדשה, התחלות חדשות, כדוגמת פרסום ה gem שדיברתי עליו, וגם החלטתי לעשות משהו שכבר מספר שנים אני חושב עליו: לכתוב תוסף ללזרוס שיאפשר לעשות split view על עורך טקסט.split_view

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

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

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

ואז מסתבר כי לפחות החלק של הבאפר, זה הדבר הקל ביותר בסיפור, ולקח לי כחצי שעmy first pluginsה כולל מחקר (שלקח את רוב הזמן) ליצור כמו שצריך את הבדיקה, ואז לשפצר אותה להיות נכונה תכנותית (למשל DRY).

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

השלב הבא בניסוי יהיה לרשום גם קיצור מקשים למקלדת על אותו תוסף.

HOT כי זליגת מידע לא מעניינת אותנו

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

SMS By HOT

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

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

ניסיתי לפנות בדוא"ל לדואר שממנו שלחו לי את החשבונית, והוא לא תיבה קיימת.

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

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

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

hot

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

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

והנה מספר שאלות עבורכם כחומר מחשבה:

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

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

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

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

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

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

ה gem הראשון שלי

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

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

אני חייב לציין שזה היה פשוט מידי לעשות את המהלך. הרשמה לrubygems, הורדת ה gemcutter מרובי gem, יצירת ה gem ואז ביצוע push עם הדוא"ל והסיסמה של rubygems וזהו 🙂

אני יודע שסטטיסטיקה חשובה לכם, אז נכון לכתיבת הפוסט היו 40 הורדות של ה gem פחות מ24 שעות לאחר הפרסום שלו, שלדעתי לפחות זה מדהים 🙂

מצגות בעולם הרחב של הרשת

מאז 2007, התחלתי להעביר הרצאות, חלקם ללקוחות בתשלום, ורובם קהילתיים לגמרי.

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

עד היום הייתי במידת הצורך יוצר שקפים באמצעות Impress של Libre/Open Office (בהתאם לקיומם בעולם), וכבר הרבה זמן שאני חושב להתחיל לעשות את זה קצת אחרת.

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

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

אז החלטתי ללכת על משהו בין מה שגוגל מציעים לבין impress.js, ומצאתי את reveal.js.
המערכת מציעה להעביר מצגות, עם תמיכה ב html5, css3 ו javascript. אבל אינה דורשת ממני לתכנת דברים, אלא להתמקד בתוכן, וכיצד אני רוצה שהוא יוצג. למעשה התכנות שלי זה html הכי מינימליסטי בעולם. המפתח שלה אפילו חשב על תמיכה בשפות כמו עברית, ולאפשר לנו להציג הרצאה מימין לשמאל לפי בחירה.

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

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

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

May the source be with you 🙂

Struct, OpenStruct ושמירת מידע ברובי

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

  1. Struct
  2. OpenStruct

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

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

התחלת עבודה עם struct:

Users = Struct.new(:username, :password, :salt, :first_name, :middle_name, :last_name, :email)
user = Users.new(:first_name => 'i')
user.username = 'ik'
user[:password] = 'secret'
user[2] = 'pepper'
user['email'] = 'spamme@example.com'
...

למעשה בהדגמה הזו, יצרתי מחלקה עם שדות בשם Users, המחלקה מכילה את שדות username, password, salt, first_name, middle_name, last_name ו email.
לאחר מכן, יצרתי אובייקט בשם user מהמחלקה Users ובעת היצירה הזנתי את השדות במספר צורות כדוגמת שימוש ישיר בשם השדה, שימוש בסימבול המייצג את השם של השדה, המיקום של השדה בסדר שיצרנו את השדות ושימוש בשם השדה, וכמובן בעת היצירה עצמה של האובייקט.

התחלת העבודה עם OpenStruct:

require 'ostruct' # mandatory to support it

user = OpenStruct.new(:username => 'joe', salt: 'sea')
user.password = '1234'

כאן יצרנו אובייקט בשם user אשר קיבל בעת היצירה שני שדות: username ו salt. כאשר OpenStruct מחייב בצורה הזו להזין להם גם ערכים.
לאחר מכן, הגדרנו שדה בשם password ונתנו לו ערך.
אלו הדרכים שאפשר להזין ולהשתמש במידע עם OpenStruct.