תאימות אחורה

13/12/2020

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

* 20e950e Use Object.create(null) to avoid default object property hazards
* a2c5da8 (tag: v1.3.8) 1.3.8
* af5c6bb Do not use Object.create(null)
* 8b648a1 don't test where our devdeps don't even work
* c74c8af (tag: v1.3.7) 1.3.7
* 024b8b5 update deps, add linting
* 032fbaf Use Object.create(null) to avoid default object property hazards

שימו לב מלמטה למעלה לקומיטים שקשורים ל Object.create:

  1. קומיט 032fbaf עבר להשתמש ב Object.create(null)

  2. קומיט af5c6bb חוזר ל Object.create רגיל

  3. וקומיט 20e950e חוזר ל Object.create(null)

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

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

config.hasOwnProperty(blah)

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

והקומיט האחרון שחוזר ל Object.create(null) ? נו, זאת בדיוק הסיטואציה שבגללה פותחים גירסה 2 של הספריה ושוברים תאימות אחורה.

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