ज़्यादातर प्रोजेक्ट में पता सत्यापन और सामान्यीकरण को एक ही गतिविधि मान लिया जाता है, और इस भ्रम की कीमत टीमें असली समय के रूप में चुकाती हैं। इनमें से एक मान का रूप ऐसा बदलता है कि एक ही पते की दो वर्तनियां आपस में मेल खाने लगें; दूसरा यह जवाब देने की कोशिश करता है कि वह पता मौजूद है या नहीं और वहां डिलीवरी हो सकती है या नहीं। दोनों अलग डेटा इस्तेमाल करते हैं, अलग तरीकों से विफल होते हैं, और किसी टेस्ट सूट में पूरी तरह अलग अपेक्षाओं के हक़दार हैं।
यह लेख दोनों को अलग करता है, यह बताता है कि पूरी दुनिया की कोई पूर्ण पता सूची किसी प्राधिकरण के पास क्यों नहीं है, और यह वर्णन करता है कि इनमें से कोई एक चलाने के बाद कोई प्रणाली ईमानदारी से क्या दावा कर सकती है।
सामान्यीकरण असल में क्या करता है
सामान्यीकरण एक पुनर्लेखन है। वह उपयोगकर्ता द्वारा लिखे गए मान को लेकर उसका मानक संस्करण बनाता है — एक जैसा अक्षर-आकार, किसी एक परंपरा के अनुसार सड़क के प्रकार का पूरा या संक्षिप्त रूप, मानकीकृत दिशात्मक शब्द, एक जैसा विभाजक, किनारों से हटाया गया खाली स्थान, और एक तय रूप में लिखा गया पोस्टल कोड। कुछ भी सत्यापित नहीं होता। जो मान कभी किसी असली स्थान से जुड़ा ही नहीं था, वह उतने ही करीने से सामान्यीकृत हो जाता है जितना कोई सही मान।
इसका मूल्य तुलना में है। एक ही जगह का वर्णन करने वाले दो रिकॉर्ड, जो अलग-अलग तरीकों से टाइप किए गए थे, सामान्यीकरण के बाद अक्षर दर अक्षर एक जैसे हो जाते हैं, और तब दोहराव हटाना, मिलान और खोज काम करने लगते हैं। यह भंडारण को भी स्थिर करता है — डेटाबेस में एक ही रूप होने का मतलब है कि आगे के उपभोक्ता नियम दोबारा लिखना बंद कर देते हैं।
सामान्यीकरण सस्ता, नियतात्मक और कहीं भी चलाने के लिए सुरक्षित है। इसी संयोजन की वजह से यह उस सबसे पहली सीमा पर बैठता है जिसे डेटा पार करता है — फ़ॉर्म हैंडलर, आयात स्क्रिप्ट, एपीआई प्रवेश बिंदु — और सिर्फ़ एक बार। अलग-अलग परतों में बार-बार सामान्यीकरण करना ही वह रास्ता है जिससे कोई मान दो वर्तनियों के बीच झूलता रह जाता है।
सत्यापन असल में क्या साबित करने की कोशिश करता है?
सत्यापन पूछता है कि कोई मान स्वीकार्य है या नहीं, और इसका ईमानदार जवाब पूरी तरह इस पर निर्भर है कि आपके पास कितना प्रमाण है। इस एक शब्द के पीछे तीन अलग सवाल छिपे हैं।
पहला है संरचनात्मक — क्या ज़रूरी फ़ील्ड मौजूद हैं, क्या अक्षर अनुमत समूह में हैं, क्या लंबाई विश्वसनीय है। इसमें किसी संदर्भ डेटा की ज़रूरत ही नहीं होती और यह कहीं भी किया जा सकता है।
दूसरा है संबंधात्मक — क्या पोस्टल कोड बताए गए क्षेत्र की इस्तेमाल होने वाली श्रेणी में पड़ता है, क्या राज्य कोड उससे मेल खाता है, क्या देश अपने उपप्रभाग कोड से सहमत है। इसमें संदर्भ डेटा चाहिए, पर पता डेटाबेस नहीं, और यह असली टाइपिंग गलतियों का बड़ा हिस्सा पकड़ लेता है।
तीसरा है अस्तित्वात्मक — क्या इस सड़क पर इस नंबर पर सचमुच कोई इमारत है। इसमें किसी आधिकारिक स्थानीय डेटासेट की ज़रूरत होती है, और सिर्फ़ कुछ ही देश ऐसा डेटासेट प्रकाशित करते हैं जो इसका जवाब देने के लिए पूरा हो।
ज़्यादातर प्रणालियां तीसरे का दावा करती हैं और दूसरा लागू करती हैं। यह ज़रूरी नहीं कि गलत हो, पर यह संयोग नहीं बल्कि जाना-बूझा फ़ैसला होना चाहिए, क्योंकि इसी से तय होता है कि त्रुटि संदेश ईमानदारी से क्या कह सकता है।
| सवाल | क्या पूछता है | क्या चाहिए |
|---|---|---|
| संरचनात्मक | क्या ज़रूरी फ़ील्ड मौजूद हैं, अक्षर अनुमत समूह में हैं और लंबाई विश्वसनीय है | कोई संदर्भ डेटा नहीं |
| संबंधात्मक | क्या पोस्टल कोड बताए गए क्षेत्र की श्रेणी में पड़ता है, राज्य कोड उससे मेल खाता है और देश अपने उपप्रभाग कोड से सहमत है | संदर्भ डेटा, पर पता डेटाबेस नहीं |
| अस्तित्वात्मक | क्या इस सड़क पर इस नंबर पर सचमुच कोई इमारत है | एक आधिकारिक स्थानीय डेटासेट, जिसे सिर्फ़ कुछ देश प्रकाशित करते हैं |
क्या वैश्विक पता डेटाबेस जैसी कोई चीज़ होती है?
ऐसा नहीं जो पूरा, आधिकारिक और वर्तमान हो। डाक संचालक अपने-अपने क्षेत्रों के लिए अपनी-अपनी शर्तों के तहत अपना डिलीवरी डेटा रखते हैं, और उनमें से बहुत से पता-स्तर की सूची प्रकाशित ही नहीं करते। जहां राष्ट्रीय डेटासेट मौजूद हैं, वे उसी देश को, उसी देश की भाषा और संरचना में कवर करते हैं। ऐसा कोई एक रजिस्टर नहीं है जिसे कोई विक्रेता यह तय करने के लिए देख सके कि धरती पर कहीं भी कोई मनमाना पता मौजूद है या नहीं।
विक्रेता असल में जो करते हैं, वह अलग-अलग संयोजनों में यह है — अपना जमा किया संदर्भ डेटा इस्तेमाल करते हैं, पोस्टल कोड और प्रशासनिक भूगोल से मिलान करते हैं, विश्वसनीयता के नियम लागू करते हैं, और कुछ देशों के लिए लाइसेंस प्राप्त स्थानीय डेटासेट इस्तेमाल करते हैं। इनमें से हर एक अधूरा है। जो सेवा किसी पते को मान्य बताती है, वह आम तौर पर यह बता रही होती है कि वह उस जानकारी से मेल खाता दिखता है जो उस सेवा को मालूम है, और जो सेवा उसे अवैध बताती है वह शायद सिर्फ़ उस क्षेत्र को कवर नहीं करती।
व्यावहारिक निचोड़ यह है कि पता सत्यापित हो गया, यह दावा आपकी प्रणाली पूरी दुनिया के लिए नहीं कर सकती। संरचना की दृष्टि से मान्य और हमारे पास उपलब्ध संदर्भ डेटा से मेल खाता — यह दावा वह कर सकती है, और प्रलेखन में यही लिखने लायक है।
क्रम क्यों मायने रखता है, पहले सामान्यीकरण फिर जांच
पहले सामान्यीकरण चलाएं। संदर्भ जांचें मानक रूप के विरुद्ध लिखी जाती हैं, इसलिए सामान्यीकृत न किया गया मान उनमें ऐसे कारणों से विफल होगा जिनका शुद्धता से कोई लेना-देना नहीं है — किसी और जगह विभाजक वाला पोस्टल कोड, अलग तरीके से संक्षिप्त किया गया सड़क का प्रकार, क्षेत्र के नाम में अक्षर-आकार का अंतर।
उलटा क्रम बेकार से भी बुरा है। यदि संदर्भ जांच पहले चले और मान को अस्वीकार कर दे, तो आप वह मौका खो देते हैं जिसमें सिर्फ़ बेतरतीब मान को ठीक किया जा सकता था, और उपयोगकर्ता को ऐसी त्रुटि दिखती है जिस पर वह कुछ कर ही नहीं सकता। यदि वह पहले चले और स्वीकार कर ले, तो भी बाद में सामान्यीकरण चाहिए ही, इसलिए कुछ बचता नहीं।
दूसरा क्रम-नियम त्रुटि संभालने पर लागू होता है। इसे पार्स नहीं किया जा सका, इसे संदर्भ डेटा से टकराव है, और यह हमारे कवरेज में नहीं है — इन तीनों को अलग रखें। तीनों के लिए अलग संदेश और अलग अगले कदम चाहिए, और इन्हें एक ही विफलता में मिला देने से ही पता सत्यापन उपयोगकर्ताओं को मनमाना लगने लगता है।
डेवलपर्स के लिए: नियम, ओवरराइड और फ़िक्स्चर
किसी पते को एक नियमित अभिव्यक्ति से सत्यापित करने की कोशिश न करें। बदलाव उन हिस्सों में रहता है जिनमें नियमित अभिव्यक्ति सबसे कमज़ोर है — सड़क के नाम, यूनिट की जानकारी, गैर-लैटिन लिपियां — और निश्चितता उन हिस्सों में रहती है जिन्हें सूची से जांचा जा सकता है। पैटर्न लंबाई और अक्षरों की जांच के लिए बचा रखें, और संदर्भ जांचें डेटा में रखें।
हमेशा मानवीय ओवरराइड की छूट दें। संदर्भ डेटा अधूरा है और कभी-कभी गलत भी, और जो पता वास्तव में सही है पर आपका जांचकर्ता उसे नहीं पहचानता, उसे भी चलते रहने योग्य बने रहना चाहिए। अस्वीकार किए गए मान के साथ ओवरराइड दर्ज करें, ताकि आप बता सकें कि जांचकर्ता सुधर रहा है या सिर्फ़ लोगों को परेशान कर रहा है।
अपने कोड में सामान्यीकरण और सत्यापन को अलग-अलग चरणों और अलग-अलग नामों के साथ रखें। वह फ़ंक्शन जिसका नाम पता-जांच है और जो कभी अपने इनपुट को दोबारा लिख देता है और कभी उसे अस्वीकार कर देता है, ठीक वैसी चीज़ है जिससे बग का पता लगाना असंभव हो जाता है। यही अलगाव ऐतिहासिक रिकॉर्ड पर सामान्यीकरण चलाना संभव बनाता है, जबकि सत्यापन इनपुट के द्वार की तरह लगा रहता है — यह फ़र्क टेस्ट फ़िक्स्चर में पता डेटा बनाने वाले किसी भी व्यक्ति को परिचित लगेगा।
किसी टेस्ट सूट के लिए दोनों व्यवहारों की जांच अलग-अलग करें — यह कि दिया गया बेतरतीब इनपुट सामान्यीकरण के बाद अपेक्षित मानक मान बन जाता है, और यह कि फ़ील्डों की दी गई असंगत जोड़ी अस्वीकार होती है। जब संदर्भ सूची बदले, तो सिर्फ़ दूसरा समूह ही हिलना चाहिए।
आगे के कदम
एक वाक्य में लिखें कि आज आपकी प्रणाली उन तीन सवालों में से किसका जवाब देती है, और देखें कि आपके त्रुटि संदेश उससे ज़्यादा दावा तो नहीं कर रहे। फिर एक ऐसे सही पते का फ़िक्स्चर जोड़ें जिसे आपका जांचकर्ता अस्वीकार करता है, और तय करें कि उसका क्या होना चाहिए। पता जनरेटर ऐसे मान बनाता है जो रचना से ही संरचना की दृष्टि से मान्य होते हैं, जिससे वह उन जानबूझकर तोड़े गए नमूनों के साथ एक सुविधाजनक सकारात्मक आधार रेखा बन जाता है जो आप रखते हैं। वे बस इतने ही हैं — संरचना की दृष्टि से मान्य; उन मानों को किसी गंतव्य तक पहुंचाया नहीं जा सकता और वे निवास के बारे में कुछ साबित नहीं करते। एक ऐसी असंगति की विस्तृत जांच के लिए जिसे पकड़ना आसान है, चेकआउट पता फ़ॉर्म के टेस्ट केस देखें।