Alek�ei Matiu�hkin

сделано с умом



Безопасный вызов духов

Saturday, 20 Oct 2001 Tags: 2001tech

Ванильное горе

На прошлой неделе один из моих коллег пожаловался на странное поведение его ICQ—клиента. Его респонденты получали от него читабельный русский язык во всех без исключения случаях, кроме одного. Если текст был скопирован с лучшего сайта анекдотов — адресат видел много-много маленьких вопросиков. Ну, как в русских заголовках сообщений криво настроенного Outlook'a или при отправке письма на русском в немецкий чат. Мой коллега апеллировал к трагической истории с табличками ВЫХОДА НЕТ в Парижском метро и беспокоился о нравственной стороне трансформации послания смешного анекдота в отправку бесчисленных «что делать?», «кто виноват?» и «быть, иль не быть?».

Я попытался проанализировать ситуацию. Наверняка всем известна история одного зажиточного американца, любившего дорогие автомобили и ванильное мороженое. После приобретения новой машины любимой марки, несчастный столкнулся со следующей проблемой. Этот четырехколесный друг человека, стоимостью со средних размеров дом в Голливуде, страдал нетерпимостью ко второй слабости своего хозяина. А именно, когда владелец авто ездил в супермаркет за ванильным мороженым, покупал его и собирался ехать домой — чудо американского автопрома отказывалось заводиться вплоть до необходимости вызова эвакуатора. При этом — автомобиль работал как часы при движении по городу, и даже — при поездках в тот же супермаркет за мороженым любого другого сорта.

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

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

Так же и я, возвращаясь к локальным проблемам взаимодействия ICQ и безобидных анекдотовру — должен был увидеть что-то очевидное, но не лежащее на поверхности. Предположение о ревности Аськи к Вернеру, отбирающему у праздной публики часть потраченного в интернете впустую времени, я, поколебавшись, отмел. Все-таки, у нас тут пока не совсем еще матрица. Требовалась немного более приземленная причина.

Сказки про <INPUT>

Тогда я вспомнил свои стенания по поводу юникода. И сообразил, что браузер наверняка отдает текст в буфер обмена в UTF-8, иначе он запутается с кодировками напрочь. Тот элемент управления, окошечко ввода, куда молодежь пишет тоннами всякие глупости — наверняка стандартный, пришедший с системой, и умеющий худо-бедно принимать и показывать двухбайтную кодировку. А вот дальше начинаются проблемы. Потому что стандарт для обмена сообщениями в подоконной Асе для российских пользователей — KOI-8. Коя (пардон, неудержался от каламбурчика) — однобайтна. И клиент перед отправкой сообщения — без предупреждения, суда и следствия — режет лишние вторые байтики и шлет во внешний мир так печально известные вопросики воптовых размерах.

К чему это я? Да к тому, что нет преступней халатности для программиста, чем полагаться на корректность ввода пользователя.

Ну и что?

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

Предположим, есть модальный диалог, запрашивающий дату чего-бы-то-ни-было. Метод соответствующего класса установки даты может выбрасывать исключение. Конструктор этого класса принимает два параметра: собственно объект и его метод установки даты. Кроме того, этот класс имеет метод defaultCorrectValue, который просто вызовет соответствующий метод установки снова, используя скорректированное вызывающим кодом значение параметра. Вариант использования этого класса в псевдокоде показан ниже.

newValue = showModificationDialog();
try {
    setNewValue(newValue);
} catch (BadParamException bpe) {
    newValue = showBljaIdiotEnterCorrectValue();
    bpe.retry(newValue, defaultCorrectValue);
}

Очень нетрудно заметить, что пример подходит для установок сложных типов данных; нескольких параметров сразу, — и вообще, расширяется и масштабируется на славу.

Пойду, что ли, посмотрю в доках, как еще можно над пользователями поглумиться…

Не переспрашивай дважды то, что и сам знаешь.


  ¦