А дело было так.
Правлю я там там что-то в переводчике связанное с интерфейсом взаимодействия между GUI и плагинами и в процессе тестирования вижу странное.
Берем предложение и переводим, получаем два варианта перевода. Все как ожидалось:
А теперь берем и делаем второй вариант перевода предложения основным (т.е. первым в списке переводов):
Упс! А текст-то не тот!
Надо заметить, что алгоритм сортировки вариантов перевода предложений в соответствии с предпочтениями пользователя крайне примитивен - все выбранные предложения хранятся в специальном списке. При переводе текста, по окончании процесса перевода полученные в итоге варианты сортируются. Вообщем, ну никак сортировка не может повлиять на перевод - она осуществляется в конце!
Два часа я искал проблему. Я выделил и сравнил логи перевода до и после сортировки - они совпали. Я пересмотрел алгоритм перевода (вызова модулей). Я вспомнил как работает алгоритм склонения слов и пролазил его весь под отладчиком. Я даже переписал алгоритм сортировки! Я сделал еще целую кучу действий - и ничего. До некоторого момента всё нормально, а потом - упс! - и всё плохо.
И совершенно случайно я все-таки нашел в чем была проблема... Вы не поверите.
Итак, где-то в классе TextTranslator (отвечающем за перевод текста) есть такой код:
for (k = 0; k < ersent.rus.Count;k++ )
RunProccessRVariantQueue(ersent.rus, par, sent, k);
... который в итоге вызывает такую функцию:
static void RunProccessRVariantQueue(List<trstr> snt, int par, int sent, int variant)
{
for (int i = 0; i < ModulesFactory.Instance.rvar_proccess_queue.Count; i++)
{
((IRStrVariantProcessor) ModulesFactory.Instance.rvar_proccess_queue[i].obj).ProcessRStringVariant(snt, variant, par, sent);
}
}
Модель сортировки же был сделан так же как и, например, модуль склонения слов, т.е. вызывался для каждого варианта перевода предложения. Сделано это было дабы не плодить лишних сущностей в виде специального интерфейса для модулей, которые должны работать с несколькими вариантами перевода предложения, а не только с одним (кстати, скорее всего зря - такие модули возможно были бы полезны, правда, пока что я в этом не уверен - нет соответствующих алгоритмов).
Ну и вот, чтобы не допустить ошибок при сортировке и лишних потерь в производительности, функция ProcessRStringVariant модуля сортировки начинается со строчки:
if(variant != 0) return;
... что по идее должно было заставлять выполнять сортировку один раз. И оно даже работало. Но с одним интересным побочным эффектом.
Не вдаваясь в детали, скажу, что цепочка вызовов модулей обрабатывающих эти самые варианты перевода предложения состоит из двух элементов: модуля склоения и модуля сортировки. Что же происходило и почему в итоге возникала ошибка? Рассмотрим пошагово работу алгоритма:
Итерация №1
Вызов модуля склонения для варианта №0
Вызов сортировкщика. В сортировщике стоит указние, что надо вариант с нормером 1 поставить в начало списка (т.е. сделать его номером 0).
Итерация №2
Вызов модуля склонения для варианта №1
Сортировщик ничего не делает, т.к. вариант !=0
Так вот, на итерации №1 мы имеем что? Правильно! Тот же самый вариант, что и на итерации №0, т.к. сортировщик свое дело сделал :) В результате, второй вариант перевода не склонялся.
Решением проблемы оказалась замена приведенного выше условия на следующее:
if(variant!=Count-1) return;
Вот так вот... Два часа на поиск одной единственной строчки...
Комментариев нет:
Отправить комментарий