вторник, 30 ноября 2010 г.

Путаница в параметрах №2

Это перевод Parameter confusion #2. Автор: Майкл Каплан.

Кажется, прошли годы с того момента, когда я говорил про путаницу в параметрах функции LCMapString при создании ключей сортировки.

Ох, постойте-ка, это было только вчера :-)

Существует и другое направление для возникновения путаницы - в этот раз не из-за отличий, а наоборот, из-за постоянности.

понедельник, 29 ноября 2010 г.

Путаница в параметрах

Это перевод Parameter confusion. Автор: Майкл Каплан.

Функция LCMapString выглядит так, будто бы она имеет ясный и однозначный смысл своих параметров. Посмотрите на заголовок:
function LCMapString(
  Locale: LCID;       // ИД локали
  dwMapFlags: DWORD;  // тип преобразования
  lpSrcStr: LPCTSTR;  // исходная строка
  cchSrc: Integer;    // число символов в исходной строке
  lpDestStr: LPTSTR;  // целевой буфер
  cchDest: Integer;   // размер целевого буфера
): Integer;
И для большинства типов использования LCMapString это справедливо.

Ну, кроме случая с ключами сортировки.

воскресенье, 28 ноября 2010 г.

*Другая* работа LCMapString

Это перевод LCMapString's *other* job. Автор: Майкл Каплан.

Для меня NLS API функция LCMapString делает постоянную работу, которая является критичной для фундамента Windows - генерацию ключей сортировки. Я знаю, что это критично, потому что когда я случайно напутаю в таблицах, то находятся компоненты, которые не дадут Windows запуститься, опасаясь порчи информации!

суббота, 27 ноября 2010 г.

И последнее слово о FINAL SIGMA

Это перевод The last word on the FINAL SIGMA. Автор: Майкл Каплан.

Ранее я обсудил сценарий, когда двойное изменение регистра не даёт исходную строку в .NET.

В любом случае, позавчера мне пришло письмо от какого-то читателя моего блога, ищущего все односторонние проецирования в лингвистических таблицах (доступ к которым есть через флаг LCMAP_LINGUISTIC_CASING). И он хотел знать, почему этот символ, FINAL SIGMA, не может быть просто помещён в лингвистическую таблицу, если это одностороннее проецирование.

Справедливый вопрос, и я думаю, стоящий отдельного поста в блоге :-)

пятница, 26 ноября 2010 г.

Когда изменение регистра не обратимо в .NET

Это перевод When casing does not need to roundtrip in .NET. Автор: Майкл Каплан.

Несколько дней назад я напомнил читателям, что у каждого символа есть своя история. И тогда я говорил о U+03c2 a.k.a. GREEK SMALL LETTER FINAL SIGMA.

В тёмном, далёком прошлом я также говорил о значении термина "лингвистического изменения регистра" в Windows. Но я ни разу не сказал, когда и где эта настройка используется в .NET Framework (я вот думаю: а это кто-то заметил?).

Некоторое время назад я также говорил о проблемах одностороннего проецирования регистра для грузинского.

Но это не просто путешествие назад в прошлое...

четверг, 25 ноября 2010 г.

У каждого символа есть история, часть 8: U+03c2 (GREEK SMALL LETTER FINAL SIGMA)

Это перевод Every character has a story #8: U+03c2 (GREEK SMALL LETTER FINAL SIGMA). Автор: Майкл Каплан.

GREEK SMALL LETTER FINAL SIGMA - это такой тип символа, за которым всегда остаётся последнее слово.

Этот символ (ς) используется только когда он находится в конце слова; в противном случае вы должны использовать U+03c3 (σ, a.k.a. GREEK SMALL LETTER SIGMA).

Часть его истории в стандарте Unicode описывается на этом сайте:
Final sigma - это позиционный вариант sigma (U+03C3 Greek Small Letter Sigma, σ), что также случается в иврите и арабском. Законный вопрос - нужны ли в Unicode две кодовые точки для обоих случаев; и, к примеру, ранний вариант стандарта содержал лишь одну кодовую точку, без выделения этой разницы. Однако, использование двух кодовых точек в теперь уже устаревшей кодовой странице Latin-7 решило дело в пользу двух отдельных кодовых позиций.
Этот же сайт также немного говорит об истории этой буквы в языке.

среда, 24 ноября 2010 г.

"Майкл, ну почему ToTitleCase такой отстой?"

Это перевод "Michael, why does ToTitleCase suck so much?". Автор: Майкл Каплан.

В заголовке этого поста я, на самом деле, просто процитировал e-mail, который я получил по этой теме. E-mail, так похожий на другие, которые я получаю время от времени с тех пор, как я начал публиковать заметки об особенностях изменения регистра строки. И это ещё одно из самых невинных писем!

Кажется, люди просто ненавидят класс TextInfo из-за его метода ToTitleCase.

вторник, 23 ноября 2010 г.

Какими API я владею?

Это перевод What APIs do I own? Автор: Майкл Каплан.

Вчера в комментарии к моему посту о SHAnsiToUnicode/SHUnicodeToAnsi Rosyna задала мне интересный вопрос:
Это, вообще-то, поднимает интересный вопрос. Если кто-то работает в одной группе разработчиков в MS и видит проблему в коде другой группы. И эта проблема влияет на их код, то могут ли они исправить код этой другой группы?
Вообще говоря, люди не изменяют напрямую код других групп. Но вы можете поработать с ними вместе, предоставить отзывы, своё мнение и опыт, а также помощь.

Бывают и исключения, но, по большому счёту, вещи работают именно так.

Внутри группы люди, чтобы помочь исправить баг и сбалансировать нагрузку, часто работают с кодом, который принадлежит другому человеку - мы все работаем в довольно кооперативной обстановке :-)
И когда ты работаешь в такой группе в MS, то как много там кода, который является твоей (личной) ответственностью? Одна какая-то DLL? Несколько функций в DLL? Или набор DLL одного "жанра"?
Это зависит от разработчика, группы, сложности кода и опыта. Я могу ответить только за себя, что я и попробую сделать сейчас :-)

понедельник, 22 ноября 2010 г.

Зачем нужна SHAnsiToUnicode?

Это перевод Whither SHAnsiToUnicode? Автор: Майкл Каплан.

Наш хороший друг Serge Wautier (автор утилиты appTranslator - я как нибудь напишу про неё тоже!) спросил меня в Suggestion Box:
Какова цель функции SHAnsiToUnicode? Я имею ввиду... какие преимущества она имеет в сравнении с обычной MultiByteToWideChar?

Очевидно, у неё меньше параметров. И всё?

TIA,
Очень хороший вопрос. Я и сам задумывался об этом!

Шучу-шучу :-)

воскресенье, 21 ноября 2010 г.

Несколько подсказок для CompareString

Это перевод A few of the gotchas of CompareString. Автор: Майкл Каплан.

CompareString - это одна из самых клёвых функций. Я думал так и до того, как стал её владельцем, и даже до того, как я встретил людей, которые раньше были её владельцами (или женщину, которая её написала).

Но, как и любая другая API функция, CompareString имеет свои подводные камни.

суббота, 20 ноября 2010 г.

Что сломало сообщения о языке ввода?

Это перевод What broke the input language messages?. Автор: Майкл Каплан.

Вчера, когда я говорил о роли сообщений, я сболтнул небольшой кусочек в конце:
Теперь нужно сказать, что этот процесс перестал был истиной в 100% случаев в Windows XP и выше; это так запланировано по дизайну, но, похоже, не указано ни в какой документации. Я объясню что сломало модель и почему (а также, как всё починить, чтобы работало!) завтра...
Не очень хорошо дразнить читателей, поэтому я объясню, что изменилось в XP и когда...

пятница, 19 ноября 2010 г.

Даже если сообщение направлено не вам, вы всё равно должны пропустить его

Это перевод Even if the message is not for you, you still need to pass it on. Автор: Майкл Каплан.

Когда-то давно, в начальной школе мы занимались такой вещью как передача записочек. На записке было написано имя человека, которому она предназначалась; если записка была не вам, то вы должны были передать её дальше. Конечно же, вы не должны были её выкидывать или читать.

Хотя, эти уроки, которые мы выучили в раннем возрасте, не всегда вспоминаются сейчас, когда должны были бы...

четверг, 18 ноября 2010 г.

Двойное тайное ANSI, часть 1 (где-то на полпути от ANSI к Unicode)

Это перевод Double Secret ANSI, part 1 (Somewhere between ANSI and Unicode). Автор: Майкл Каплан.

Любой, кто читает меня регулярно, знает, что я всегда предпочитаю увидеть, что приложение работает с Unicode.

Но, очевидно, в мире есть приложения, которые не поддерживают Unicode. По крайней мере сегодня.

Некоторые из этих приложений существовали уже какое-то время и они работают с ANSI довольно хорошо.

И некоторые их них даже поддерживают ANSI великолепно - вплоть до уровня "двойное тайное ANSI".

среда, 17 ноября 2010 г.

вторник, 16 ноября 2010 г.

Что, чёрт возьми, не так с TranslateCharsetInfo?

Это перевод What the hell is wrong with TranslateCharsetInfo, anyway? Автор: Майкл Каплан.

Однажды у Колина появился клиент с вопросом о неожиданном поведении функции TranslateCharsetInfo:
У моего клиента есть проблемы с API TranslateCharsetInfo. Они указывают флаг TCI_SRCLOCALE для использования LCID как источника:
fResult := TranslateCharsetInfo(langid, csi, TCI_SRCLOCALE);
Они обнаружили, что результаты этого вызова не всегда соответствуют значениям, указанным в http://www.microsoft.com/globaldev/nlsweb/default.mspx

В частности:
LCID $0C04 – Chinese (Hong Kong S.A.R.) - возвращает кодовую страницу 936 вместо ожидаемой 950
LCID $0004 - Chinese (Simplified) – возвращает кодовую страницу 950 вместо ожидаемой 936

То, что я вижу - это ожидаемое поведение или нет? Если нет, то какой есть другой способ?

Мы также попробовали:
GetLocaleInfo(langid, LOCALE_IDEFAULTANSICODEPAGE, szLocaleData, SizeOf(szLocaleData)/SizeOf(Char));
Хотя этот способ возвращает 950 для LCID $0C04 (уже лучше), но LCID $0004 всё ещё возвращает 950 вместо 936.

Или я что-то упускаю?

Many thanks,
Colin
Результаты двух значений LCID на самом деле вызваны двумя совершенно различными причинами.

понедельник, 15 ноября 2010 г.

Точность - не то же самое, что аккуратность

Это перевод Precision is not the same as accuracy. Автор: Реймонд Чен.

Аккуратность - это насколько вы близки к правильному ответу; точность - это насколько велико разрешение (количество значащих цифр) вашего ответа.

воскресенье, 14 ноября 2010 г.

Ещё о недокументированном поведении и людях, которые рассчитывают на него: выходные буферы

Это перевод More undocumented behavior and the people who rely on it: Output buffers. Автор: Реймонд Чен.

Для функций, которые возвращают данные, содержимое выходных буферов чаще всего не определено при ошибке в функции. Если функция завершается неудачей, то вызывающий не должен ничего предполагать о содержимом буферов.

Но это всё равно не останавливает людей.

суббота, 13 ноября 2010 г.

Обратная совместимость является отцом NLS функций

Это перевод Backcompat is the father of the NLS APIs. Автор: Майкл Каплан.

Некоторое время назад у меня был разговор с бесстрашным директором нашей группы Джули Беннетт. Вообще-то, она могла быть тогда менеджером нашей группы. Я завёл с ней разговор, потому что один наш клиент жаловался на то, как LCMapString работает с ключами сортировки.

Эта функция API была спроектирована так, что если вы передавали ей строку и флаг LCMAP_SORTKEY, то она возвращала вам двоичное представление строки (подходящее для использования в качестве индекса).

пятница, 12 ноября 2010 г.

Что делает строку осмысленной?

Это перевод What makes a string meaningful? Автор: Майкл Каплан.

Вчера я сказал, что CompareString предпочитает осмысленные данные и хотя (редкие) несоответствия всегда являются багами, но нам приходится приоритезировать баги, основываясь на критерии осмысленности входных данных.

Многие люди задались вопросом, как определяется здесь слово "осмысленные". Если ли тут строгое определение или что-то, полезное для разработчиков?

четверг, 11 ноября 2010 г.

CompareString предпочитает осмысленные строки

Это перевод CompareString prefers meaningful strings. Автор: Майкл Каплан.

Ещё одна причина, почему интернациональное тестирование - это не для новичков...

Как это они говорят на despair.com: "When you earnestly believe you can compensate for a lack of skill by doubling your efforts, there's no end to what you can't do".

Хотя это не проблема в этой команде. Но когда другие команды вызывают наши API, им иногда в голову приходит идея тестировать API как часть тестирования их компонента. И, не понимая как эти API работают, они пишут код, который генерирует случайные Unicode строки и передаёт их в CompareString.

среда, 10 ноября 2010 г.

ZOMG! Эта программа использует процессор на 100%!1! Подумайте о щеночках!!11!!1!1!eleven

Это перевод ZOMG! This program is using 100% CPU!1! Think of the puppies!!11!!1!1!eleven. Автор: Реймонд Чен.

По каким-то причинам люди относятся к программам, занимающих процессор на 100%, как если бы эти программы пинали ногами беззащитных (и милых) щеночков. Успокойтесь же. А то у меня уже такое впечатление, что люди считают, что столбец "Использование CPU" в Диспетчере Задач - это не диагностический инструмент, а способ подсчета, сколько щенков в секунду пинают ногами программы.

вторник, 9 ноября 2010 г.

Опрос засыпанием против опроса ожиданием с таймаутом

Это перевод Polling by sleeping versus polling by waiting with a timeout. Автор: Реймонд Чен.

Комментатор Francois Boucher спросил, в фоновом потоке лучше ли делать опрос со Sleep и флагом или опрос с ожиданием на событии?
// Метод A
while fKeepGoing do
begin
  ... немного работы ...
  Sleep(50);
end;

// Метод B
repeat
  ... немного работы ...
until (WaitForSingleObject(hEvent, 50) <> WAIT_TIMEOUT);
Какой сценарий лучше? Первый использует только один описатель - для потока. Второй использует два. Тратит ли первый пример больше потокового времени? Стоит ли использовать ещё и событие (объект ядра)?"

понедельник, 8 ноября 2010 г.

Следствия из алгоритма планировщика: засыпание помогает не всегда

Это перевод Consequences of the scheduling algorithm: Sleeping doesn't always help. Автор: Реймонд Чен.

Чаще всего я вижу проблемы, обратные к теме "поток с низким приоритетом может работать даже когда в системе есть активный поток с высоким приоритетом". А именно: люди, которые думают, что Sleep(0) является чистым способом отдать процессор (yield). Например, у них могли закончиться вещи, которые можно делать, и они просто хотят, чтобы другой поток делал работу.

Вспомните, что планировщик потоков ищет готовый выполняться поток с самым высоким приоритетом - а если их несколько, то все они равноправны. Поток может вызвать Sleep(0), чтобы отдать остаток своего кванта времени раньше срока, уменьшая, таким образом, свою долю в работе процессора. Заметьте, однако, что это не гарантирует, что запустится другой поток.

воскресенье, 7 ноября 2010 г.

суббота, 6 ноября 2010 г.

Как писать как Реймонд: что я трижды сказал, то и верно

Это перевод How to write like Raymond: What I tell you three times is true. Автор: Реймонд Чен.

Очередная часть в крайне единичной серии о том, как писать так, как Реймонд.

пятница, 5 ноября 2010 г.

Судья не даст этой строке веса

Это перевод The jury will give this string no weight. Автор: Майкл Каплан.

(заголовок сделан под вдохновением от полтора десятилетия Law & Order на NBC, затем A&E, а сейчас - TNT!)

Я не хочу ругаться на сравнения (collation) в Windows, потому что я считаю, что они сделаны круто. Они покрывают большую территорию и работают (и работают хорошо) в большей части мира. Однако иногда вы можете обнаружить, что вы находитесь на острой грани, отделяющей поддерживаемые возможности. А когда вы на такой грани - то важно не порезаться. Поэтому я попробую поговорить о таких краевых случаях...

четверг, 4 ноября 2010 г.

Почему/как создавалось MSLU...

Это перевод Why/how MSLU came to be, and more. Автор: Майкл Каплан.

Один вопрос, который мне постоянно задают (его регулярно задают даже сегодня): почему Microsoft создало MSLU?

Посмотрим, сумею ли я пролить немного света на этот вопрос.

среда, 3 ноября 2010 г.

Понимание хэш-кодов

Это перевод Understanding hash codes. Автор: Реймонд Чен.

Чаще, чем просто один раз, я вижу вопросы вроде таких:
У меня есть процедура, которая создаёт строки динамически. И мне нужна формула, которая берёт строку и делает небольшой уникальный идентификатор для этой строки (хэш-код), так что две одинаковые строки имели бы одинаковый идентификатор, а две различные строки - различный. Я пытался использовать String.GetHashCode, но у неё есть случайные совпадения. Какой есть способ, чтобы создать уникальный хэш?

вторник, 2 ноября 2010 г.

Имена программ в обработчиках типов файлов должны быть полными

Это перевод Program names in file type handlers need to be fully-qualified. Автор: Реймонд Чен.

Многие люди не замечают этого, но в Windows XP SP 2 было сделано изменение в требованиях для обработчиков типов файлов: пути к программам теперь должны быть заданы полностью, если программа находится вне каталога Windows или System.

Причина: безопасность с лёгким налётом предсказуемости.

понедельник, 1 ноября 2010 г.

20/97: Выпускайте программу раньше и часто

Это перевод Deploy Early and Often. Автор: Steve Berczuk.

Из "97-ми вещей, которые должен знать каждый программист".

Отладка процесса развёртывания и установки программы часто откладывается на конец проекта. В некоторых проектах, написание утилиты установки даётся заданием инженеру, который относится к ней как к "неизбежному злу". Обзоры и демонстрации обычно выполняются в окружениях, собранных вручную - чтобы гарантировать, что всё пройдёт без запинки. В результате команда не имеет опыта с процессом установки и возможных рабочих окружениях, пока не станет слишком поздно вносить изменения.