מדינה מול שפה הם שני צירים שונים, והתקלה הנפוצה ביותר בנתוני בדיקה היא להתייחס אליהם כאל ציר אחד. ערך מדינה עונה על שאלה בדבר חוקים, מערכות קידוד ומוסכמות מקומיות; ערך שפה עונה על שאלה בדבר מה שנכתב על המסך ובאיזה סדר. שני הצירים חופפים לעתים קרובות מספיק כדי ליצור את הרושם שהם אותו דבר, והם נבדלים בדיוק במקומות שבהם מערכת נשברת.
המאמר הזה מפריד בין השניים ומתייחס ללוקליזציה כאל שלושה רבדים נפרדים. הוא מסביר מה כל אחד מן הצירים שולט בו, מה נשבר כאשר התבנית של השדה הולכת אחרי השפה במקום אחרי האזור, וכיצד לדגום את שניהם במטריצת בדיקות בלי שמספר הצירופים יתפוצץ.
מדוע אין לגזור מדינה משפה או שפה ממדינה?
היחס בין מדינה לשפה אינו פונקציה. מדינה אחת יכולה להחזיק כמה שפות רשמיות, ושפה אחת מדוברת בכמה מדינות שלכל אחת מהן מוסכמות אחרות לגמרי. ההנחה של שפה אחת למדינה אחת נראית נכונה כל עוד המבט נשאר על מפה מצומצמת.
בלגיה היא הדוגמה השגרתית ביותר: שלוש שפות רשמיות תחת קוד מדינה אחד, ולכן סדר השמות בכתובת ובשם האדם יכול להשתנות בתוך אותה מדינה עצמה. שווייץ, קנדה, הודו ודרום אפריקה מרחיבות את הרשימה, וכל אחת מהן שוברת את ההנחה בדרך אחרת. בכיוון ההפוך, ספרדית נפוצה לאורך עשרות מדינות, וקוד האזור נשאר הדבר היחיד שקובע איך נראה מיקוד ואיך נראה מספר זהות.
ההפרדה הזאת לבדה מצדיקה להחזיק שני שדות ולא אחד, משום שכל ניסיון לאחד אותם דורש בסופו של דבר כלל חריג. כל כלל חריג הוא מקום שבו מישהו בעתיד יניח את ההנחה השגויה מחדש.
לוקליזציה היא בעצם שלושה רבדים
לוקליזציה מתייחסת בדרך כלל לשלושה רבדים שאינם זזים יחד, וכדאי להתייחס אליהם בשמותיהם בסכמת הנתונים ולא בשם כללי אחד.
רובד הממשק הוא מה שהמשתמש רואה: שפת התוויות, כיוון הפריסה, תבנית התאריך ותבנית המספר. רובד התוכן הוא מה שנכתב לתוך המערכת בשפה שאינה בהכרח שפת הממשק: שמות פרטיים, שמות רחוב ושמות מקומות שנשארים בצורתם המקורית. רובד הנתונים הוא איך נשמרים ומוצגים ערכים בעלי צורה קבועה, כגון מיקוד, מספר טלפון ומספר זהות, ואלה נקבעים בידי האזור ולא בידי השפה.
| רובד | מה הוא קובע | הגורם השולט |
|---|---|---|
| שפת ממשק | תוויות, כיוון, תבנית תאריך ומספר | העדפת המשתמש והשפות הנתמכות |
| אזור תוכן | שמות ומקומות בצורתם המקורית | המקום שבו נוצר התוכן |
| תבנית נתונים | מיקוד, טלפון, מספר זהות | האזור או המדינה של הנתון |
שלושת הרבדים האלה יכולים לנוע בנפרד. מתרגם יכול להוסיף שפה בלי לגעת בשדה נתונים אחד; מדינה יכולה לשנות תבנית מיקוד בלי שאף תווית מתורגמת תשתנה. מערכת שבה שלושתם נגזרים ממשתנה אחד קוראת לזה לוקליזציה אבל מתנהגת כמו בחירת ערכה.
רובד התוכן הוא גם המקום שבו התאמת שמות מדינות וכינויים נכנסת לתמונה, משום ששם שנכתב בידי משתמש באותה שפה יכול עדיין להירשם בצורה שאינה זהה לשם הקנוני שהמערכת מצפה לו.
תג השפה וקוד האזור עושים עבודות שונות
תג שפה כגון de או pt-BR מתאר את שפת הטקסט ואת העדפת הכתיבה. קוד אזור כגון DE או BR מתאר את ההקשר הגאוגרפי שאליו שייכת הנתונה. הם חופפים לעתים קרובות, וזה בדיוק המקור לבלבול.
התג מתאים למחרוזות שהמשתמש קורא. הוא מתאים לבחירה איזו גרסה של הודעה להציג, איזה סדר של שם משפחה ושם פרטי להציג, ואיזו תבנית תאריך להגיש. הקוד מתאים למחרוזות שנכתבות לפי כלל: מיקוד בעל ספרת ביקורת, מספר טלפון בעל קידומת, מזהה בעל סכום ביקורת. רק אחד משני אלה יכול לשמש כמקור לתבנית של שדה נתונים.
ההבחנה חשובה משום שהחלפה ביניהם אינה מייצרת שגיאה קורעת אלא תוצאה סבירה. המערכת תפיק מיקוד באורך הנכון ובתבנית הלא נכונה, וזו בדיוק התקלה שהכי קשה להבחין בה בעין. דוגמה מן הצד השני: יפן היא מדינה שבה השפה והאזור כמעט תמיד מופיעים יחד, וזו הסיבה שהדוגמה הזאת אינה חושפת את הבעיה כלל.
מה נשבר כאשר התבנית הולכת אחרי השפה?
כאשר התבנית של שדה נגזרת משפת הממשק, שדות נכשלים בדיוק ברגעים המעניינים. משתמש ששינה את שפת הממשק לשפה מוכרת כדי לקרוא תוויות שהתרגל אליהן מקבל לפתע שדות בתבנית שאינה שייכת למדינה שבה מוזנת הכתובת.
התקלה הזאת חוזרת בכל מקום שבו שני הצירים מוצגים באותו מסך. טופס הרשמה בשפה אחת עם כתובת במדינה אחרת יציג את התבנית הלא נכונה, וכל בדיקה שנכתבת מול אותו טופס תעבור. הבדיקה לא תזהה את הפגם משום שהיא עצמה נבנתה על אותה הנחה שגויה, וזו הסיבה שבדיקות כאלה שורדות חודשים ארוכים בסביבת בדיקות.
יש לזכור גם את הכיוון ההפוך: אותו שינוי במדינה בלי שינוי בשפה משנה את הנתונים. מעבר ממדינה בעלת מיקוד ספרתי למדינה בעלת מיקוד אלפאנומרי אינו נוגע בתווית אחת, והוא עדיין משבית כל מאמת שלא עודכן. שני הכיוונים חייבים להיבדק בנפרד, משום שכל אחד מהם מפיל שדות אחרים.
כיצד מטריצת בדיקות דוגמת שני צירים?
מטריצת בדיקות של שני צירים מתפוצצת בקלות. עבור עשר מדינות וחמש שפות מדובר בחמישים צירופים, ורובם המכריע אינו מעניין מבחינת סיכון.
הדרך המעשית היא לדגום את שני הצירים בנפרד ורק אחר כך להוסיף צירופים ממוקדים. עמודת המדינות צריכה להכיל דוגמה מן הליבה, דוגמה מן המקרה הקשה ודוגמה מן הקצה; עמודת השפות צריכה להכיל שפה הנכתבת מימין לשמאל, שפה שאינה נכתבת בכתב לטיני, ושפה הנכתבת באותו כיוון של הממשק. שתי העמודות נבנות בנפרד, וכל אחת מהן נבדקת בפני עצמה.
הצירופים הממוקדים נשמרים למקומות שבהם שני הצירים נוגעים זה בזה באמת. שם של אדם בשפה אחת בתוך כתובת במדינה אחרת, מיקוד בתבנית מקומית בתוך ממשק בשפה זרה, ומספר טלפון שנכתב בהקשר אזורי אחר מזה של המשתמש. אלה הצירופים שמצדיקים בדיקה נפרדת; כל השאר הוא כפילות שמוסיפה זמן ריצה בלי להוסיף כיסוי.
למפתחים: לתת לאזור להוביל את התבנית
בסכמת הנתונים, התבנית צריכה להיגזר מן האזור ולא מן השפה. שדה התבנית צריך לשאת אזור, והשפה צריכה להופיע רק במקום שבו היא באמת קובעת משהו, כגון תווית, סדר שדות או תבנית תאריך.
יש לקרוא לשדות בשמות שמתארים את תפקידם ולא את מקורם, כדי שמי שקורא את השדה בעוד שנה יידע איזה ציר הוא מייצג. שדה ששמו נגזר משפת מערכת בעוד אורכו נגזר ממדינה הוא בדיוק הבלבול שהמאמר הזה מנסה למנוע. מדריך המדינות והאזורים אוסף את ערכי המדינה במקום אחד, ולכן הוא מקום סביר לקרוא ממנו מה כל אזור באמת קובע.
כל ערך המופיע לעיל הוא להמחשה. שמות השפות, קודי האזורים והצירופים המוזכרים כאן הם דוגמאות בדיוניות שנכתבו לצורך הסבר מידול, ואין להסיק מהן דבר על התנהגות של מערכת אמיתית.
צעדים הבאים
יש לבחור שדה אחד ולבדוק מה בפועל קובע את התבנית שלו. אם התשובה היא שפה, זה הפער שיש לתקן לפני שמוסיפים שפה נוספת, משום שכל שפה חדשה תכפיל אותו. המדריך לבדיקת שדה בחירת מדינה ממשיך ברמת הרכיב עצמו, והמדריך לקיבוץ אזורים ודירוגי שווקים מסביר כיצד לקבץ את ערכי האזור בלי לערבב אותם עם צירים אחרים.