Vlad писал(а):
Александр Ильин писал(а):
А по поводу данного примера, то в пределах своего модуля я имею право считать, что eof - это не физический конец файла, а логический конец обработки данных моим модулем. В конце концов, переменная sym не видна извне, и её значение я определяю по своему усмотрению.
Тем не менее. Вы теряете контроль над тем кто и когда читает/меняет переменную. Например, при появлении многопоточности такой код можно сразу переписывать, никакая синхронизация вас уже не спасет :) Да и без многопоточности разобраться будет непросто. Уж лучше явно код ошибки везде тащить.
Про явно тащить код ошибки - это интересное соображение! Я раньше не понимал, почему переменная sym в парсере сделана глобальной, а теперь понял! Ведь в самом деле "тащить" её через все процедуры параметром было бы громоздко. А так - вот она, переменная состояния парсера. Многопоточность реализуется элементарно: процедуры модуля делаются методами объекта, переменная sym - полем объекта. Объект работает в пределах одного потока.
Что касается контроля над чтением/изменением - достаточно всякое присвоение оформить отдельной процедурой с говорящим названием. Т.е. вместо OPS.Read вызывать всегда местный Read. Это и будут точки синхронизации и прочей обработки. Правда, убедиться в том, что не производится присвоения в неположенных местах, можно будет только вручную с помощью поиска по исходнику... Вот тут я бы подкрутил дополнительный контроль к компилятору, если придумать такой синтаксис... Например, заставить процедуры IMPORT'ировать глобальные переменные из собственного модуля (из других модулей и так импортируются через указание имени модуля, так что поиск тут работает). В том числе только для чтения. Либо квалифицировать каким-то словом (MODULE? Идентификатором модуля?). Первый вариант кажется лучше из-за возможности read-only, а второй - из-за последовательности (consistency).