пятница, 9 июля 2010 г.

Where is the locale? "Its Invariant." In where?

Это перевод Where is the locale? "Its Invariant." In where? Автор: Майкл Каплан.

Старая шутка, адаптированная для Windows XP (прим. пер.: как и заголовок, я решил оставить без перевода, ибо при переводе полностью теряется смысл):

Q -- Where is the locale?
A -- Its invariant.
Q -- Where is variant?
A -- Its ten miles south of communicado, and five miles east of Cognito.

Инвариантная локаль (invariant locale) - это довольно странная штука. Давайте взглянем на её любопытные характеристики:
  • У неё нет ассоциированного языка.
  • У неё нет региона.
  • Нет страны.
  • Не показывается в перечислениях а-ля EnumSystemLocale.
  • Её данные выбраны так, чтобы удержать людей от попыток использовать её как локаль.
  • Не используется в Office, SQL Server или любом другом продукте, который показывает список локалей пользователю.
Тогда почему она вообще существует?

Ну, для этого нам надо вернуться к сравнению (collation).

В сравнении символов для Windows существует таблица по-умолчанию, которая даёт порядок сортировки для каждой возможной кодовой точки в Unicode. Как я заметил в моей заметке ранее, Microsoft не использует UCA, а эта таблица по-умолчанию существует уже много-много лет. Новые кодовые точки добавляются в неё по мере расширения поддержки языков в Windows. И самая важная вещь в этой таблице: она поддерживает любой язык, который может сосуществовать с другими без конфликтов - вроде английского, греческого, арабского и немецкого (далеко не полный список!). Это не значит, что в этих языках одинаковые правила сортировки - нет. Просто у них нет ничего конфликтующего в их порядке сортировки с другими языками из этого списка (потому что либо они вовсе не пересекаются по символам алфавита, либо они сортируют разделяемые символы одинаковым образом). К примеру, все эти языки имеют не-конфликтующие правила для таких символов:

A
a
Å
o
Ö
Z
α
β
γ
ب
ح
د

Теперь, для сравнения, посмотрите на порядок сортировки этих же символов в шведском языке (отличия отмечены красным):

A
a
o
Z
Å
Ö
α
β
γ
ب
ح
د

Очевидно, что шведский язык не может быть обработан по этой таблице, потому что шведские "Å" и "Ö" рассматриваются как раздельные буквы, располагаемые после "Z", вместо того, чтобы считать их как "A" и "O" с чёрточками (диакритическими знаками), как это имеет место в английском. Поэтому шведский не обрабатывается по таблице по-умолчанию, как некоторые другие языки.

(См. Приложение D из первого издания Developing International Software for Windows 95 and Windows NT для ещё более интересных вещей, подобных этому)

Часто люди наживают себе проблемы, пытаясь использовать LOCALE_USER_DEFAULT или LOCALE_SYSTEM_DEFAULT для сортировок, порядок которых не должен меняться. А любая из этих двух локалей может быть изменена пользователем или администратором в любое время. И это приводит к багам в коде таких программ. Поэтому команда NLS рекомендует, чтобы люди использовали MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)) = $0409 - не потому, что мы пытаемся быть провинциалами (в конце концов, для этой же цели равно подошли бы немецкий, русский, арабский или другие языки), а затем, чтобы задать неизменяемый порядок для сортировок, которые не должны меняться при изменениях пользовательских настроек.

Конечно же, люди будут рассматривать использование фиксированной константы $0409 (также известной как "US English") как признак того, что Microsoft - это просто провинциальная корпорация в US. Поэтому, чтобы не сражаться с подобным впечатлением, была добавлена новая локаль (поскольку начальной целью всё равно было просто "использовать таблицу весов по-умолчанию" для сортировок). Новая локаль, которая не изменяется, не варьируется. Которая будет... ИНВАРИАНТНОЙ. Вот как в Windows XP родилась локаль LOCALE_INVARIANT - 136-я локаль, добавленная в Windows.

Не самая плохая вещь, да?

Такая же штука существует и в .NET Framework - через статический член CultureInfo.InvariantCulture. Использование инвариантной локали выглядит странно для вещей вроде дат и чисел, но зато она производит согласованные результаты при сравнениях и сортировке, потому что всегда использует таблицу по-умолчанию.

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.