שבוע עם Atom

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

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

העורך משתמש בחלקים של כרומיום, ב node.js, ומשתמש גם ב coffeescript עבור התצוגה של דברים (הנעשים בcss).

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

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

העניין הוא ש 1.0 קרוב להיות משהו טוב, אבל ישנם מספר דברים שעדיין לא אפויים מספיק:

  • היכולת להגדיר מה הוא API תקין מבחינת תוספות ולא לאפשר תוספות שאינן כאלו
  • היכולת להגדיר תוספים על בסיס מה שאני עובד כרגע
  • קבלת תוספים איכותיים מבית github לשפות שונות, כדוגמת PHP, רובי וכיוב', מעבר למה שמגיע כברירת מחדל.

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

פורסם בקטגוריה atom, ide and editors, ui, טכנולוגיה, פיתוח, קוד פתוח, תוכנה, תכנות | השארת תגובה

recursive tail

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

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

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

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

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

הגישה המוכרת ביותר לכך נקראת tail recursion. או רקורסיית זנב בעברית טכנית.

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

מה הכוונה? אשתמש בקוד רובי (שהוא לדעתי קריא מאוד) לשם כך.

רקורסיה בגישה ה"רגילה" תהיה כתובה כך:

def recursive(n)
  if n <= 1
    1
   else
     n * recursive(n - 1)
   end
end

recursive(4)
=> 24

רקורסיית זנב, תראה כך:

def tail_recursive(current, n, result)
  return result if current <= n

  new_result = result * current
  tail_recursive(current + 1, n, new_result)
end

tail_recursive(1, 4, 1)
=> 24

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

אבל לא הכל ורוד בזה. קשה יותר לדבג בעיות ברקורסיית זנב, היות ולמעשה אין לנו stack frames רבים, שיהיה ניתן להבין באיזה שלב יש בעיה. ובכך אין לנו stack trace שיסייע לנו בנושא.

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

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

פורסם בקטגוריה Python, Ruby, טיפים וטריקים, טכנולוגיה, פיתוח, קוד פתוח, תוכנה, תכנות | השארת תגובה

חשיבה מופשטת

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

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

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

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

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

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

אבל זה לא הכל. גם לעיצוב בhtml יש תיאור, למשל בשביל להגיד שcss הוא עבור המסך. זה נקרא media types.

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

אני מסביר לדפדפן כי הדף שנטען הוא למשל בקידוד של UTF-8, ואני מסביר לדפדפן כי אסור לו לבצע זום.

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

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

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

מה זה מאפשר לנו להשיג אם זה בhtml (ולא, זה לא דומה אפילו לתכנות)?
דבר ראשון, זה אומר שאנחנו טוענים פחות מידע. למשל יש עכשיו את פרוטוקול HTTP/2. הפרטוקול אומר כי בגלל שיש המון מידע שצריך להטען, במקום לחכות לכל המידע הזה, אני אכניס הכל בבקשה אחת ואצור multiplexing.
טעינה של המון לוגיקה ב Javascript, טעינה של המון CSS שלא לדבר על תוכן שאולי רק לא יוצג ב HTML, כולם יוצרים בעיות ביצועים. אך במידה ואנחנו נוכל לטעון רק את המידע הרלוונטי כאשר הוא רלוונטי בלבד, אז למעשה כמות המידע ירד, ולמרות ש HTTP/2 הוא נחמד, עדיין אשיג אופטימיזציה מצויינת רק מעצם זה שאני לא טוען מידע שאני לא זקוק לו.

אז איך ניתן להשיג את כל זה בלי תכנות? סתם רעיון, לא באמת הדרך הנכונה:

<div src="/foo.html" alt="no content" media="(max-wdith: 640px and max-height: 480px)">

הנה עוד בעיה, אתרים עובדים עם bootstrap בגרסה 3.3.4 (לצורך ההדגמה בלבד), ובאתר הראשון שנכנסתי אליו שמשתמש בו, אני מקבל עותק מקומי שעשה minified אבל למעט ה copyright נמחקו כל ההערות בפנים.
האתר השני בכלל משתמש ב cdn. האם הדפדפן שלי ידע כי מדובר באותה גרסה בדיוק? לא! אבל מה אם אוכל לתאר לו שזה המצב? האם זה לא יוסיף לי אופטימיזציה? האם זה לא יוסיף לי מהירות של חוסר טעינה מחודשת של המידע? האם זה לא יוריד את כמות התעבורה לטעינת bootstrap בגרסה זו?

הנה הדגמה גם לזה:

<link href="/styles/bootstrap.min.css" rel="stylesheet" provides="bootstrap" ver="3.3.4">

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

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

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

מעניין איך תפתרו את ה"תרגיל" למעלה …

פורסם בקטגוריה אינטרנט, אתרי אינטרנט, פיתוח, קוד פתוח, תוכנה, תכנות, תקשורת | 9 תגובות

הבעיות שיש לי עם תכנות ריספונסיבי

הקדמה

אנחנו חיים בעולם שיש בו המון מילות באזז, כדוגמת big data, responsive design, cloud computing, סייבר וכיוב' …
כל המילים האלו מגיעות מעולם השיווק, אבל לאדם טכני לא באמת אומרות הרבה.

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

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

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

מונחי יסוד

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

CSS – הם קבוצה של חוקים אשר יכולים לכסות אחד את השני (מכאן השם: Cascading Style Sheet) בצורה שתספק עיצוב למסמך.

הסבר

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

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

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

כך שאולי יש מסמך איכותי עם המון מידע, שמעוצב מדהים ויודע להיות מוצג בהרבה רזולוציות, אבל האם הוא באמת יודע להגיב כמו שצריך למגבלות המכשיר אשר המסמך מוצג בו?

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

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

פורסם בקטגוריה Operating Systems, ui, אינטרנט, אתרי אינטרנט, חומרה, טכנולוגיה, סלולרי, פיתוח, קוד פתוח, רשתות, תוכנה, תקשורת | 9 תגובות

הרעיון של תכנון מערכות גמישות – חלק ראשון

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

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

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

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

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

כך גם הגישה של actor model שבה אנחנו מקבלים משהו שיודע לשלח בקשות ולקבל תשובות, אך זה לא חייב להיות אותו החלק.

גישה נוספת אשר מפשטת מאוד פיתוח, אך קשה יותר לתכנון נקראת micro services.
הרעיון הוא די פשוט ואנחנו מכירים אותו למעשה מעולם היוניקס: יש משהו קטן שיודע לעשות פעולה אחת ורק אותה, ולהחזיר אותה הלאה.
למשל מכירים את הפקודה cat? היא יודעת להציג פלט מתוך "קובץ" – בברירת המחדל ל sdout.
אם נשלב אותה עם sort למשל, נוכל עכשיו לסדר שורות לפי סדר מסויים שנבחר. אם נשלב עוד תוכנה בשם uniq, עכשיו נעיף כל מה שחוזר על עצמו, ונקנח בפקודה tr, אשר תתרגם לנו סוף שורה לפסיק, ועכשיו נשים את הכל בקובץ חדש, והנה יצרנו מערכת יחסית מסובכת המשתמשת בפעולות מאוד מאוד פשוטות.

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

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

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

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

בחלק הבא, אכנס קצת יותר בצורה טכנית וקצת פחות תיאורטית.

פורסם בקטגוריה טכנולוגיה, פיתוח, קוד פתוח, תוכנה, תכנות | 5 תגובות

הפרוטוקולים המהירים של גוגל

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

עם המהלך הזה של גוגל יצאו 2 פרוטוקולים מאוד מעניינים:

  1. SPDY – אשר כרגע עובר להית HTTP/2
  2. QUIC – היכולת לקחת את UDP ולתת לו רק חלק מהתכונות של TCP

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

העניין הוא, שבSPDY, יש שימוש בפרוטוקול TCP, והוא, כאשר יש משהו שנמשך הרבה זמן הופך להיות סוג של blocking עד שהבקשה הארוכה הזו מסתיימת.
אז איך מאיצים את זה?
אפשר לחשוב על UDP. הבעיה היא שהוא חסר state. כלומר או שעבר לי מידע או שלא, אבל אני לא יכול לדעת מעבר לזה, וזה אומר שבשביל לדעת אם משהו ביצע, אני יוצר עוד סוג של over-head וזה ליצור בתוך המידע שלי יכולת לדעת אם משהו הצליח או לא.

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

כרגע יש שמועות שבנוסף לHTTP שעבורו תוכנן QUIC, הפרוטוקול יהיה בשימוש בעוד מקומות, כמו למשל webrtc, אך זה רק שמועות כרגע, ונראה שהולך להיות מאוד מעניין :)

פורסם בקטגוריה Google, webrtc, אינטרנט, טכנולוגיה, קוד פתוח, תוכנה, תקשורת | עם התגים , , , , , , | השארת תגובה

פונקציה מונדית

אחד הדברים שאני שומע מהרבה אנשים אשר מתעסקים בתכנות פונקציונאלי הוא שפונקציה מונדית (monad function) היא בערך התשובה לכל מה ש42 לא מצליח לכסות.

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

הנה קוד ג'אווה סקריפט (מבוסס jQuery) קצר שאסביר אותו עוד מעט:

$('#id').html('<p>success</p>').addClass('success')

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

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

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

function init() {
  var self = this;
  return {
     callMe : function() {
       return self;
     }
  };
}

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

הרעיון לשימוש בקוד יהיה בגישה הבאה:

init().callMe().someOtherMethod() ...

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

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

פורסם בקטגוריה javascript, טכנולוגיה, פיתוח, קוד פתוח, תכנות | עם התגים , , , , , | תגובה אחת

אנשי DBA

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

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

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

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

למשל בכל מסדי הנתונים שאני מכיר, יש בעיה עם Foreign keys. הם נשמעים טוב, אבל מוסיפים סיבוכיות בכך שהם בעצם מתורגמים לעוד פעולת select. את בעיית הביצועים הזו גיליתי לבד, את הסיבה לכך, ובכן איש DBA הסביר לי. אבל הוא באמת מבין המון דברים. הפתרון לכך פשוט, אבל זה לא נושא הפוסט :)

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

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

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

פורסם בקטגוריה טכנולוגיה, יעוץ, מסדי נתונים, פיתוח, קוד פתוח, תכנות | עם התגים , , , , | 6 תגובות

האלמות

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

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

פורסם בקטגוריה כללי | השארת תגובה

סינטרה מודולרית

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

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

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

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

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

אנחנו משתמשים בRack בעצם, היות וכמעט וכל הframeworks עבור בניית מערכות web ברובי משתמשים בו, אנו זקוקים לקובץ קבוע בשם config.ru.

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

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

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

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

למערכת שיצרתי ישנם שני מצבים – מערכת לדיבוג REST, ומערכת "בדיקות" אשר עליה אפשר לבדוק שדברים עובדים, והיא בעיקר על תקן "echo" כלשהו.

את המערכת של יצירת המסכים, ושליחת ה REST, יצרתי בקובץ rest.rb, והכל מאוגד שם.
יש שם משהו שהולך לעבור למקום אחר בקרוב, וזה מספר מתודות לסיוע בפעולות.

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

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

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

במקרה הזה, הגדרתי כי במצב של ‎:development משתמשים ב Sinatra::Reloader, אשר מגיע עם Sinatra-Contrib – תת פרוייקט המספק הרבה כלי עזר לדברים שונים.
הסיבה לשימוש ב Reloader הוא לא לאתחל את השרת בכל שינוי שעושים למחלקה של סינטרה, כאשר Reloader מגלה כי התוכן של הקובץ השתנה, הוא גורם ל rack לטעון אותו שוב, וככה אנחנו לא זקוקים לטעינה מחודשת של השרת עצמו.

המערכת שכתבתי, משתמשת ב template בשם haml, למעשה פעם ראשונה אשר אני משתמש בה מרצון. תוכלו למצוא את ה layout.haml שהוא המסגרת הרגילה וכן כרגע קובץ בשם index.haml תחת ספריית view.
ועבור העיצוב, אני משתמש ב Foundation 5, אשר אני אוהב אותה יותר מאשר bootstrap.
עבור Javascript יש גם את jQuery וגם את knockout.js, כאשר אני נעזר גם ב lodash.js למספר דברים פשוטים, והיא מספקת בעצם גרסה שעברה אופטימיזציה ל underscore.

את הקבצים של Foundation, וכל ה Javascript ניתן למצוא תחת public.

דבר אחרון שנשאר לספר עליו הוא שאני משתמש במשהו אשר נקרא puma.
מה זה ?
puma הוא משהו שלוקח את rack וגורם לו להיות שרת לכל דבר ועניין, אשר ניתן לבצע עליו חיבור לשרתי HTTP שונים, כדוגמץ apache או nginx.
החיבור נעשה על ידי הגדרת proxy בשרתים.

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

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

פורסם בקטגוריה Ruby, ui, unix, אינטרנט, טיפים וטריקים, טכנולוגיה, לינוקס, פיתוח, קוד פתוח, רשתות, שרתים, תוכנה, תכנות, תקשורת | 2 תגובות