ماذا حدث للحظة؟
تبيّن أنّ اقتراحًا لميزات لغة 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
واجهة برمجة تطبيقات خاصة بـ MooTools):
for (var key in Array.prototype) {
Elements.prototype[key] = Array.prototype[key];
}
يتكرر for
-in
على سمات "enumerable"، وهذا لا يتضمن طرقًا أصلية مثل Array.prototype.sort
، ولكنه يتضمن خصائص يتم تعيينها بانتظام مثل Array.prototype.foo = whatever
. في المقابل،
إذا استبدلت سمة غير قابلة للتعداد، مثل
Array.prototype.sort = whatever
، ستبقى هذه السمة غير قابلة للتعداد.
في الوقت الحالي، ينشئ Array.prototype.flatten = mooToolsFlattenImplementation
خاصية flatten
قابلة للعدّ، لذلك يتم نسخها لاحقًا إلى Elements
. ولكن إذا شحنت المتصفحات إصدارًا أصليًا من flatten
، يصبح غير قابل للتعداد ولن يتم نسخه إلى Elements
. أي رمز برمجي يعتمد على
Elements.prototype.flatten
في MooTools معطّل الآن.
على الرغم من أنّه يبدو أنّ تغيير Array.prototype.flatten
الأصلي ليصبح
قابلاً للعدّ قد يؤدي إلى حلّ المشكلة، إلا أنّه من المحتمل أن يؤدي إلى حدوث المزيد من
مشاكل التوافق. سيحصل كل موقع إلكتروني يعتمد على for
-in
للتكرار على
صفيف (وهي ممارسة سيئة، ولكنّها تحدث) على
تكرار حلقة إضافي للسمة flatten
.
والمشكلة الأساسية الأكبر هنا هي تعديل الكائنات المضمنة. يُعدّ استخدام نماذج أولية برمجية أساسية لتمديد الوظائف من الممارسات السيئة بشكل عام في الوقت الحالي، لأنّه لا يتوافق بشكل جيد مع المكتبات الأخرى والرموز البرمجية التابعة لجهات خارجية. لا تعدِّل العناصر التي لا تملكها.
فلماذا لا نحتفظ بالاسم الموجود ونقطع الويب فقط؟
في عام 1996، قبل أن تنتشر لغة CSS على نطاق واسع، وقبل أن تصبح لغة HTML5 متوفّرة، تم نشر موقع Space Jam الإلكتروني. لا يزال الموقع الإلكتروني يعمل بالطريقة نفسها التي كان يعمل بها قبل 22 عامًا.
كيف حدث ذلك؟ هل كان هناك شخص يحافظ على هذا الموقع الإلكتروني طوال هذه السنوات، ويُجري تعديلات عليه في كل مرة يطرح فيها مورّدو المتصفّحات ميزة جديدة؟
تبيّن أنّ "عدم تعطيل الويب" هو مبدأ التصميم الأول للغات HTML وCSS وJavaScript وأي معيار آخر يستخدم على نطاق واسع على الويب. إذا أدّى طرح ميزة جديدة في المتصفّح إلى إيقاف عمل المواقع الإلكترونية الحالية، سيكون ذلك أمرًا سيئًا للجميع:
- يواجه زوّار المواقع الإلكترونية المتأثرة فجأةً تجربة استخدام متعطّلة.
- مالك الموقع الإلكتروني كان يمتلك موقعًا إلكترونيًا يعمل بشكلٍ مثالي، ولكن أصبح الموقع الإلكتروني غير فعّال بدون أن يُجري أي تغييرات
- يفقد مورّدو المتصفّحات الذين يطرحون الميزة الجديدة حصّة السوق، لأنّ المستخدمين يبدّلون المتصفّحات بعد ملاحظة أنّ "الميزة تعمل في المتصفّح X".
- بعد معرفة مشكلة التوافق، يرفض مورّدو المتصفحات الآخرون إرسال التطبيق. لا تتطابق مواصفات الميزة مع الواقع ("لا شيء سوى الخيال")، مما يضر عملية توحيد المقاييس.
بالتأكيد، بعد النظر إلى الوراء، اتّخذت MooTools القرار الخاطئ، ولكنّ تعطيل الويب لا يعاقب هذه الشركة، بل يعاقب المستخدمين. لا يعرف هؤلاء المستخدمون ما هي أداة moo. بدلاً من ذلك، يمكننا العثور على حلّ آخر، ويمكن للمستخدمين مواصلة استخدام الويب. يمكنك بسهولة تحديد ما إذا كنت تريد استخدام هذه الميزة أم لا.
هل يعني ذلك أنّه لا يمكن أبدًا إزالة واجهات برمجة التطبيقات السيئة من Web Platform؟
يعتمد ذلك على بعض العوامل. في حالات نادرة، يمكن إزالة الميزات الضارّة من الويب. إنّ معرفة ما إذا كان من الممكن إزالة ميزة ما هو أمر صعب للغاية، ويتطلب جمع بيانات قياسية مكثفة لتحديد عدد صفحات الويب التي قد يتغيّر سلوكها. ولكن يمكن إجراء ذلك عندما تكون الميزة غير آمنة بما يكفي أو ضارة بالمستخدمين أو نادرًا ما يتم استخدامها.
نذكر <applet>
و<keygen>
وshowModalDialog()
جميعها أمثلة على واجهات برمجة التطبيقات غير الصالحة التي تمت إزالتها بنجاح من منصة الويب.
لماذا لا نكتفي بإصلاح MooTools؟
من الجيد تعديل MooTools كي لا تمتدّ إلى الكائنات المضمّنة. ومع ذلك، لا يحلّ هذا الإجراء المشكلة الحالية. حتى إذا تم إصدار إصدار معدَّل من MooTools، يجب أن يتم تحديث جميع المواقع الإلكترونية الحالية التي تستخدمه لإزالة مشكلة التوافق.
ألا يمكن للمستخدمين تحديث نسختهم من MooTools؟
في عالم مثالي، ستطلق MooTools رمز تصحيح، وسيتم تحديث كل موقع إلكتروني يستخدم MooTools بشكل سحري في اليوم التالي. تم حلّ المشكلة، أليس كذلك؟
للأسف، هذا غير واقعي. حتى إذا تمكّن أحد الأشخاص من تحديد المجموعة الكاملة من المواقع الإلكترونية المتأثرة، وتمكن من العثور على معلومات الاتصال بكل موقع إلكتروني منها، والتواصل بنجاح مع جميع مالكي المواقع الإلكترونية، وإقناعهم جميعًا بإجراء التعديل (ما قد يعني إعادة تنظيم قاعدة الرموز البرمجية بالكامل)، ستستغرق العملية بأكملها سنوات في أحسن الأحوال.
يُرجى العِلم أنّ العديد من هذه المواقع الإلكترونية قديمة ومن المحتمل أنّها لم يتم الاحتفاظ بها. حتى إذا كان مشرف الصيانة لا يزال موجودًا، فمن المحتمل أنه ليس مطور ويب ذو مهارات عالية مثلك. لا يمكننا أن نتوقع من الجميع تغيير موقعهم الإلكتروني الذي تم إنشاؤه قبل 8 سنوات بسبب مشكلة في التوافق مع الويب.
كيف تتم عملية TC39؟
وTC39 هي اللجنة المسؤولة عن تطوير لغة JavaScript من خلال معيار ECMAScript.
أدّى الهاشتاغ #SmooshGate إلى اعتقاد البعض أنّ "اللجنة التقنية 39 تريد إعادة تسمية flatten
إلى
smoosh
"، ولكنّه كان مجرد مزحة داخلية لم يتم توضيحها جيدًا للجهات الخارجية.
لا يتم اتخاذ القرارات الرئيسية، مثل إعادة تسمية اقتراح، بشكل عفوي، ولا يتم اتخاذها
بواسطة شخص واحد، ولا يتم اتخاذها بالتأكيد بين عشية وضحاها استنادًا إلى أحد
التعليقات على GitHub.
تعتمد مجموعة TC39 عملية إعداد واضحة لاقتراحات الميزات.
تتم مناقشة اقتراحات ECMAScript وأي تغييرات رئيسية تطرأ عليها (بما في ذلك إعادة تسمية الطُرق) خلال اجتماعات 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
في الإصدار 6.9 من V8 و Chrome 69.