שאלות נפוצות על SmooshGate

למה ה-smoosh קרה?!

הצעה ל-JavaScript שמכונה Array.prototype.flatten לא תואם לאינטרנט. משלוח התכונה ב-Firefox Nightly גרם לאתר פופולרי אחד לפחות להפסיק. מכיוון שהקוד הבעייתי הוא חלק מכלי ה-MooTools הנרחבים סביר להניח שיש עוד אתרים מושפעים. (למרות שכלי MooTools לא היה נפוץ באתרים חדשים ב-2018, הוא היה בעבר פופולרי עדיין קיימת באתרים רבים בסביבת הייצור.)

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

מה Array.prototype.flatten עושה?

Array.prototype.flat, ההצעה המקורית בתור Array.prototype.flatten, משטח מערכים באופן רקורסיבי עד לערך depth שצוין, שמוגדר כברירת מחדל אל 1.

// Flatten one level:
const array = [1, [2, [3]]];
array.flat();
// → [1, 2, [3]]

// Flatten recursively until the array contains no more nested arrays:
array.flat(Infinity);
// → [1, 2, 3]

אותה הצעה כוללת Array.prototype.flatMap, כלומר מלבד זאת, הפונקציה Array.prototype.map מיישרת את התוצאה למערך חדש.

[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]

מה המטרה של MooTools שגורמת לבעיה הזו?

ל-MooTools מוגדרים גרסה לא סטנדרטית של Array.prototype.flatten:

Array.prototype.flatten = /* non-standard implementation */;

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

לצערנו, קורה משהו אחר. כלי MooTools מעתיקים את כל שיטות של מערך מותאם אישית ל-Elements.prototype (כאשר Elements הוא API ספציפי ל-MooTools):

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}

for-in מופיע באיטרציות על מאפיינים שניתנים לספירה, לא כולל שיטות נייטיב כמו Array.prototype.sort, אבל הן כוללות נכסים שמוקצים באופן קבוע, כמו Array.prototype.foo = whatever. אבל – וזאת הכותרת המקדימה – אם מחליפים נכס שלא ניתן למנות, למשל Array.prototype.sort = whatever, הוא נשאר ללא ספירה.

כרגע, Array.prototype.flatten = mooToolsFlattenImplementation יוצר נכס flatten שניתן להזין בו ספירה, לכן הוא מועתק אל Elements. אבל אם דפדפנים שולחים גרסה מותאמת של flatten, היא לא ניתנת לספירה, לא הועתקה אל Elements. כל קוד שמבוסס על MooTools Elements.prototype.flatten לא תקין.

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

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

למה לא נשמור את השם הקיים ונשבר את האינטרנט?

ב-1996, לפני ששירות ה-CSS התפשט, והרבה לפני ש-"HTML5" הפך דבר, האתר של Space Jam התחיל לפעול. היום האתר עדיין פועל בדיוק כמו לפני 22 שנים.

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

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

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

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

האם זה אומר שלעולם לא ניתן להסיר ממשקי API לא תקינים מפלטפורמת האינטרנט?

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

<applet>, <keygen> וגם showModalDialog() כולם דוגמאות לממשקי API לא תקינים שהוסרו בהצלחה מפלטפורמת האינטרנט.

למה לא פשוט מתקנים את MooTools?

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

אנשים לא יכולים לעדכן את העותק שלהם של MooTools?

בעולם מושלם, חברת MooTools תשיק תיקון וכל אתר השימוש ב-MooTools יתעדכן באורח פלא ביום הבא. הבעיה נפתרה, נכון?!

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

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

איך פועל תהליך TC39?

TC39 הוא הוועדה שאחראית על פיתוח שפת ה-JavaScript באמצעות בתקן ECMAScript.

#SmooshGate גרם לאנשים מסוימים להאמין ש"TC39 רוצה לשנות את השם של flatten ל- smoosh", אבל זו הייתה בדיחה שלא הוזנה בתקשורת טובה עם גורמים חיצוניים. החלטות חשובות, כגון שינוי שם של הצעה, לא מתקבלות בקלות ראש, ולא נלקחות בחשבון על ידי אדם יחיד, ובהחלט לא נלקחים בחשבון בן לילה, תגובה מ-GitHub.

TC39 פועל על פי תהליך Staging ברור להצעות של תכונות. הצעות ECMAScript וכל שינוי משמעותי בהן (כולל method של שינוי שם) נדון בפגישות של TC39, וצריכים לקבל אישור של כל הוועדה לפני שהם הופכים רשמיים. במקרה של Array.prototype.flatten, ההצעה כבר עברה מספר בשלבי ההסכם, עד לשלב 3, שמעיד על כך שהתכונה מוכן ליישום בדפדפני אינטרנט. הוא נפוץ במקרים נוספים של מפרטים שאתם נתקלים בבעיות במהלך ההטמעה. במקרה הזה, התנאי החשוב ביותר המשוב התקבל אחרי שניסית לשלוח אותו: התכונה, במצב הנוכחי שלה, קוטע את האינטרנט. בעיות כאלה שקשה לחזות מראש הן חלק מהסיבה לכך תהליך TC39 לא מסתיים רק לאחר שדפדפנים שולחים תכונה.

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

שינוי השם מ-flatten ל-smoosh (גם אם זו לא הייתה בדיחה) מעולם לא נדון בפגישה של TC39. לכן, העמדה הרשמית של TC39 הנושא הזה לא ידוע כרגע. אף אחד לא יכול לדבר בשם כל נתוני TC39 עד להגיע להסכמה בפגישה הבאה.

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

איך נפתרה ב-SmooshGate בסופו של דבר?

במהלך הפגישה של TC39 במאי 2018, #SmooshGate נפתרה באופן רשמי על ידי שינוי השם של flatten ל-flat.

Array.prototype.flat ו-Array.prototype.flatMap נשלחים ב-V8 גרסה 6.9 Chrome 69.