SmooshGate के बारे में अक्सर पूछे जाने वाले सवाल

क्या हुआ?!

Array.prototype.flatten नाम की JavaScript भाषा की सुविधा के लिए प्रस्ताव, वेब के साथ काम नहीं करता. Firefox Nightly में इस सुविधा को शिप करने की वजह से, कम से कम एक लोकप्रिय वेबसाइट काम नहीं कर रही थी. समस्या वाला कोड, MooTools लाइब्रेरी का हिस्सा है. इसलिए, हो सकता है कि इस समस्या का असर कई और वेबसाइटों पर भी पड़ा हो. (हालांकि, MooTools का इस्तेमाल 2018 में नई वेबसाइटों के लिए आम तौर पर नहीं किया जाता है, लेकिन यह बहुत लोकप्रिय था और अब भी कई प्रोडक्शन वेबसाइटों पर मौजूद है.)

सुझाव देने वाले व्यक्ति ने, काम न करने की समस्या से बचने के लिए, flatten का नाम बदलकर smoosh करने का सुझाव दिया. सभी लोगों को यह मज़ाक़ समझ नहीं आया. कुछ लोगों ने गलतफ़हमी में यह मान लिया कि नए नाम का फ़ैसला पहले ही हो चुका है. इसके बाद, चीज़ें तेज़ी से आगे बढ़ीं.

Array.prototype.flatten क्या करता है?

Array.prototype.flat को मूल रूप से Array.prototype.flatten के तौर पर प्रस्तावित किया गया था. यह फ़ंक्शन, तय किए गए depth तक, ऐरे को बार-बार फ़्लैट करता है. 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 */;

MooTools के flatten को लागू करने का तरीका, सुझाए गए स्टैंडर्ड से अलग है. हालांकि, समस्या यह नहीं है! जब ब्राउज़र में 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, “एन्यूमेरेबल” प्रॉपर्टी पर बार-बार चलता है. इसमें 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 में, सीएसएस के आम तौर पर इस्तेमाल होने से पहले और “एचटीएमएल5” के आने से काफ़ी पहले, Space Jam की वेबसाइट लाइव हो गई थी. आज भी यह वेबसाइट उसी तरह काम करती है जिस तरह 22 साल पहले करती थी.

ऐसा कैसे हुआ? क्या इन सभी सालों में किसी व्यक्ति ने उस वेबसाइट को मैनेज किया है और हर बार ब्राउज़र वेंडर की नई सुविधा लॉन्च होने पर उसे अपडेट किया है?

एचटीएमएल, सीएसएस, JavaScript, और वेब पर बड़े पैमाने पर इस्तेमाल किए जाने वाले किसी भी अन्य स्टैंडर्ड के लिए, “वेब को न तोड़ें” सबसे पहला डिज़ाइन सिद्धांत है. अगर ब्राउज़र की किसी नई सुविधा को लॉन्च करने पर, मौजूदा वेबसाइटें काम करना बंद कर देती हैं, तो यह सभी के लिए बुरा है:

  • जिन वेबसाइटों पर इस समस्या का असर पड़ा है उन पर आने वाले लोगों को अचानक खराब उपयोगकर्ता अनुभव मिलता है;
  • वेबसाइट के मालिकों की वेबसाइट, पूरी तरह से काम करने वाली से काम न करने वाली वेबसाइट में बदल गई, जबकि उन्होंने कुछ भी नहीं बदला;
  • नई सुविधा को शिप करने वाले ब्राउज़र वेंडर का मार्केट शेयर कम हो जाता है. ऐसा इसलिए होता है, क्योंकि उपयोगकर्ताओं को यह पता चलने के बाद कि “यह सुविधा X ब्राउज़र में काम करती है”, वे ब्राउज़र बदल लेते हैं;
  • जब ब्राउज़र के साथ काम करने से जुड़ी समस्या का पता चल जाता है, तो अन्य ब्राउज़र वेंडर इसे शिप करने से मना कर देते हैं. सुविधा की जानकारी, असल स्थिति से मेल नहीं खाती (“सिर्फ़ एक काल्पनिक कहानी”), जो स्टैंडर्ड बनाने की प्रोसेस के लिए सही नहीं है.

हां, अब MooTools ने गलत काम किया है — लेकिन वेब को बंद करने से, MooTools को सजा नहीं मिलती, बल्कि उपयोगकर्ताओं को सजा मिलती है. इन उपयोगकर्ताओं को नहीं पता कि मू टूल क्या है. इसके अलावा, हम कोई दूसरा समाधान ढूंढ सकते हैं, ताकि उपयोगकर्ता वेब का इस्तेमाल जारी रख सकें. यह विकल्प चुनना आसान है.

क्या इसका मतलब है कि वेब प्लैटफ़ॉर्म से खराब एपीआई कभी नहीं हटाए जा सकते?

यह कई बातों पर निर्भर करता है. कुछ मामलों में, वेब से खराब सुविधाओं को हटाया जा सकता है. किसी सुविधा को हटाना मुमकिन है या नहीं, यह पता लगाना भी बहुत मुश्किल है. इसके लिए, ज़्यादा टेलीमेट्री की ज़रूरत होती है, ताकि यह पता लगाया जा सके कि कितने वेब पेजों के व्यवहार में बदलाव होगा. हालांकि, जब कोई सुविधा पूरी तरह से सुरक्षित न हो, उपयोगकर्ताओं के लिए नुकसानदायक हो या उसका इस्तेमाल बहुत कम किया जाता हो, तो ऐसा किया जा सकता है.

<applet>, <keygen>, और showModalDialog(), ऐसे खराब एपीआई के उदाहरण हैं जिन्हें वेब प्लैटफ़ॉर्म से हटा दिया गया है.

हम MooTools को ठीक क्यों नहीं करते?

MooTools को पैच करना एक अच्छा आइडिया है, ताकि यह अब बिल्ट-इन ऑब्जेक्ट को एक्सटेंड न करे. हालांकि, इससे समस्या हल नहीं होती. भले ही, MooTools का पैच किया गया वर्शन रिलीज़ किया गया हो, लेकिन साथ काम करने से जुड़ी समस्या को ठीक करने के लिए, इसका इस्तेमाल करने वाली सभी मौजूदा वेबसाइटों को अपडेट करना होगा.

क्या लोग MooTools की अपनी कॉपी को अपडेट नहीं कर सकते?

अगर सब कुछ ठीक-ठाक होता, तो MooTools कोई पैच रिलीज़ करता और MooTools का इस्तेमाल करने वाली हर वेबसाइट अगले दिन अपने-आप अपडेट हो जाती. समस्या हल हो गई, अगर हां, तो बताएं!

माफ़ करें, ऐसा नहीं हो सकता. भले ही, कोई व्यक्ति किसी तरह से उन वेबसाइटों के पूरे सेट की पहचान कर ले जिन पर असर पड़ा है, उनमें से हर एक की संपर्क जानकारी ढूंढ ले, सभी वेबसाइट के मालिकों से संपर्क कर ले, और उन सभी को अपडेट करने के लिए मना ले (इसका मतलब हो सकता है कि उनके पूरे कोड बेस को फिर से तैयार करना पड़े), लेकिन पूरी प्रोसेस में कम से कम सालों लगेंगे.

ध्यान रखें कि इनमें से कई वेबसाइटें पुरानी हैं और हो सकता है कि इनका रखरखाव न किया जा रहा हो. भले ही, मॉड्यूल को मैनेज करने वाला व्यक्ति अब भी मौजूद हो, लेकिन हो सकता है कि वह आपके जैसे बेहतरीन वेब डेवलपर न हो. हम यह उम्मीद नहीं कर सकते कि वेब के साथ काम करने से जुड़ी समस्या की वजह से, सभी लोग अपनी आठ साल पुरानी वेबसाइट को बदल दें.

TC39 की प्रोसेस कैसे काम करती है?

ECMAScript स्टैंडर्ड की मदद से, JavaScript भाषा को बेहतर बनाने की ज़िम्मेदारी TC39 कमिटी की है.

#SmooshGate की वजह से, कुछ लोगों को लगा कि “TC39, flatten का नाम बदलकर smoosh करना चाहता है”, लेकिन यह एक मज़ाक था. इसे बाहरी लोगों को ठीक से नहीं बताया गया था. किसी प्रस्ताव का नाम बदलने जैसे अहम फ़ैसले, हल्के में नहीं लिए जाते. ये फ़ैसले एक व्यक्ति नहीं लेता. साथ ही, GitHub पर किसी एक टिप्पणी के आधार पर, रातों-रात ये फ़ैसले नहीं लिए जाते.

सुविधा के प्रस्तावों के लिए, TC39 साफ़ तौर पर स्टेज करने की प्रोसेस पर काम करता है. ECMAScript के प्रस्तावों और उनमें किए गए किसी भी बड़े बदलाव (जैसे कि किसी तरीके का नाम बदलना) पर, TC39 की मीटिंग के दौरान चर्चा की जाती है. इन बदलावों को आधिकारिक तौर पर लागू करने से पहले, पूरी कमिटी की मंज़ूरी लेनी पड़ती है. Array.prototype.flatten के मामले में, प्रस्ताव को सहमति के कई चरणों से गुज़रना पड़ा है. यह तीसरे चरण तक पहुंच गया है. इससे पता चलता है कि यह सुविधा वेब ब्राउज़र में लागू करने के लिए तैयार है. आम तौर पर, लागू करने के दौरान स्पेसिफ़िकेशन से जुड़ी और समस्याएं आ सकती हैं. इस मामले में, सबसे अहम सुझाव/राय या शिकायत, इसे रिलीज़ करने के बाद मिली: इस सुविधा की मौजूदा स्थिति में, वेब पर काम नहीं करता. इस तरह की समस्याओं का अनुमान लगाना मुश्किल होता है. इसलिए, ब्राउज़र में कोई सुविधा लॉन्च होने के बाद भी, TC39 की प्रोसेस पूरी नहीं होती.

TC39, सहमति के आधार पर काम करती है. इसका मतलब है कि किसी भी नए बदलाव के लिए, कमिटी को सहमत होना होगा. भले ही, smoosh कोई गंभीर सुझाव हो, लेकिन ऐसा हो सकता है कि समिति के किसी सदस्य ने compact या chain जैसे सामान्य नाम के पक्ष में, उस पर आपत्ति की हो.

flatten से smoosh में नाम बदलने के बारे में, TC39 की किसी भी मीटिंग में कभी बात नहीं की गई. भले ही, यह एक मज़ाक ही क्यों न हो. इसलिए, फ़िलहाल इस विषय पर TC39 का आधिकारिक रुख क्या है, इसकी जानकारी नहीं है. अगली मीटिंग में सहमति मिलने तक, कोई भी व्यक्ति TC39 के सभी सदस्यों की ओर से बात नहीं कर सकता.

आम तौर पर, TC39 की मीटिंग में अलग-अलग बैकग्राउंड के लोग हिस्सा लेते हैं: कुछ लोगों के पास प्रोग्रामिंग भाषा के डिज़ाइन का कई सालों का अनुभव होता है, कुछ लोग ब्राउज़र या JavaScript इंजन पर काम करते हैं, और JavaScript डेवलपर कम्यूनिटी का प्रतिनिधित्व करने के लिए, मीटिंग में हिस्सा लेने वाले लोगों की संख्या लगातार बढ़ रही है.

आखिरकार, SmooshGate को कैसे ठीक किया गया?

मई 2018 की TC39 मीटिंग के दौरान, flatten को flat में बदलकर, #SmooshGate को आधिकारिक तौर पर ठीक किया गया.

Array.prototype.flat और Array.prototype.flatMap, V8 v6.9 और Chrome 69 में शिप किए गए.