Есть такая проблема: при движении курсора по StringGrid нужно выводить в
хинте текущую информацию (ну например содержимое ячейки над, которой сейчас
мышь или координаты мыши, неважно).
Пишу для StringGrid обработчик OnMouseMove, там всё вроде есть и координаты
(x,y) и т.д. Но строка
StringGrid1.Hint := IntToStr(x)+':'+IntToStr(y);
вроде бы никакого действия на уже показываемый хинт не оказывает (хинт
появляеться только один раз, свое местоположение и содержание не меняет). В
то время как добавленная в тот же обработчик строка типа:
Form1.Caption:=IntToStr(x)+':'+IntToStr(y);
успешно трудиться!!! :(
Где я неправ? Или это вообще стандарными средствами не делаеться? :(
С уважением, Парамошин Владимир.
================================
E-mail: fi...@paramoshin.com
Thu Oct 24 2002 14:56, Vladimir Paramoshin wrote to All:
> Пишу для StringGrid обработчик OnMouseMove, там всё вроде есть и
> координаты (x,y) и т.д. Hо строка
> StringGrid1.Hint := IntToStr(x)+':'+IntToStr(y);
> вроде бы никакого действия на уже показываемый хинт не оказывает (хинт
> появляеться только один раз, свое местоположение и содержание не меняет).
http://groups.google.com/groups?selm=9v53f2%244vg%241%40host.talk.ru
С уважением, LVT
"Leonid Troyanovsky" <lv...@eco-pro.ru> сообщил/сообщила в новостях
следующее: news:18451...@p2.f175.n5020.z2.ftn...
> Приветствую, Vladimir.
>
> http://groups.google.com/groups?selm=9v53f2%244vg%241%40host.talk.ru
Спасибо за помощь, после переделки помогло! Но разве можно сначала сказать:
const
OldCol: Longint=-1; OldRow : Longint = -1;
а потом сделать:
OldRow:= ARow;
OldCol:= ACol;
С какой версии эхотага такое стало возможным? Может всё-таки это должны быть
переменные?
Или я как жена Линкольна, пропустил всё самое важное? :)
> Спасибо за помощь, после переделки помогло! Но разве можно сначала
сказать:
>
> const
> OldCol: Longint=-1; OldRow : Longint = -1;
>
> а потом сделать:
>
> OldRow:= ARow;
> OldCol:= ACol;
>
> С какой версии эхотага такое стало возможным? Может всё-таки это должны
быть
> переменные?
Дык... а разве в турбо паскале типизированных констант еще не было? (я
конечно могу уже склерозить за давностию лет по этому поводу...)
---
С уважением - Евгений Касьяненко,
Донецк, Украина
To understand recursion, we must first understand recursion
Vladimir Paramoshin wrote:
> Спасибо за помощь, после переделки помогло! Но разве можно сначала сказать:
> const
> OldCol: Longint=-1; OldRow : Longint = -1;
> а потом сделать:
> OldRow:= ARow;
> С какой версии эхотага такое стало возможным? Может вс╦-таки это должны быть
> переменные?
> Или я как жена Линкольна, пропустил вс╦ самое важное? :)
В общем-то, ты прав, и так делать не очень хорошо, потому, как такие трюки
препятствуют повторному использованию кода. Т.е., лучше делать это полями класса,
производного от T*Grid. Хотя, если делать своего наследника, возможно, найдутся
и более удачные решения.
А по поводу типизированных констант - было это с давних пор, а теперь, слава Богу,
появились и более прямые конструкции.
--
С уважением, LVT.
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru
"Evgeny Kassyanenko" <jak...@donapex.net> сообщил/сообщила в новостях
следующее: news:ap931u$m65$1...@ddt.demos.su...
>
> > Спасибо за помощь, после переделки помогло! Но разве можно сначала
> сказать:
> >
> > const
> > OldCol: Longint=-1; OldRow : Longint = -1;
> >
> > а потом сделать:
> >
> > OldRow:= ARow;
> > OldCol:= ACol;
> >
>
> Дык... а разве в турбо паскале типизированных констант еще не было? (я
> конечно могу уже склерозить за давностию лет по этому поводу...)
Да нет, к типизированным константам никаких притензий -- они были в
ТрубоПаскале и есть в Дельфях!!!
Но с каких пор можно записать в константу новое значение в теле процедуры???
А именно это и сделано -- см. пример!
А если такие штуки теперь стало можно делать, то объясните в чем тогда
теперь разница между константой и переменной?
> > Дык... а разве в турбо паскале типизированных констант еще не было? (я
> > конечно могу уже склерозить за давностию лет по этому поводу...)
>
> Да нет, к типизированным константам никаких притензий -- они были в
> ТрубоПаскале и есть в Дельфях!!!
> Но с каких пор можно записать в константу новое значение в теле
процедуры???
> А именно это и сделано -- см. пример!
То есть? А чем отличается тело процедуры от любого другого "тела"?
Типизированные константы - они по определению поддаются изменению. Оставим в
стороне целесообразность и т.п., примем это как факт. И это появилось
задолго до Дельфи - см. любую книжку по турбопаскалю.
> А если такие штуки теперь стало можно делать, то объясните в чем тогда
> теперь разница между константой и переменной?
Во-первых, не теперь, а давно. Тебя интересует разница между _константой_ и
переменной или между _типизированной_ константой и переменной? С точки
зрения особенностей написания кода или с точки зрения распределения памяти?
;)
В общем, все это есть в разделах хелпа по Object Pascal, а вкратце, не
вдаваясь в тонкости реализации - для кодера это означает возможность
инициализировать переменную сразу при ее объявлении.
hint: Константа и Типизированная константа - совсем разные вещи.
Fri Oct 25 2002 12:12, Vladimir Paramoshin wrote to Evgeny Kassyanenko:
> OldCol:= ACol;
> говорит "Left side cannot be assigned to", а у Вас???
> Delphi7, если кому интересно:
Теперь, видимо, по умолчанию {$J-} {$WRITEABLECONST OFF}
С уважением, LVT
> А у нас Project -> Options -> Compiler -> [X] Assignable typed constants
Понято, но IMHO(именно имхо!!!, не бейте и не будем спорить) это есть
надругательство над идеей констант (и паскакалем папаши Вирта), поэтому я
делаю их всё-таки:
var
OldCol: Longint=-1; OldRow : Longint = -1;
вместо
const
OldCol: Longint=-1; OldRow : Longint = -1;
Пусть переменые менянются, а уж константы(типизированные или нет) будут
константами.
Должно же в этом проклятом мире быть хоть что-то постоянным!!! :)))
Еще раз всем спасибо за отклики и помощь, но думаю тему пора закрыть или
вынести ее за пределы данной эхи...
Начиная с Delphi6 в типизированные константы по умолчанию запись запрещена.
Разрешается запись элементарным включением галочки Project -> Options ->
Compiler -> Assignable typed constants и сохранением этой опции по
умолчанию.
(непонятно, чем им запись не нравилась? Меня постоянно дергают новички,
которые сели за d6 и пытаются на ней запустить старые (до d6) проекты)
начиная с D2 можно писать так:
var
zeroVal :interger = 0;
тут никакие галочки мешать не будут.
--
Alexander Grischenko
mailto:gra...@mailbox.riga.lv
Fri Oct 25 2002 16:18, Dmitry Beloshistov wrote to Leonid Troyanovsky:
AG> var zeroVal :interger = 0;
LT> Кстати, zeroVal и так нулем инициализируется.
> Hадеяться на то, что что-то где-то по умолчанию чем-то инициализируется -
> стремно вообще-то... Hа "брюки превращаются...." похоже ;))
Вроде бы, не одни лишь надежды.
D3 help.ariable declarations:
If a global variable declaration does not explicitly specify an initial
value, the memory occupied by the variable will initially be set to zero.
С уважением, LVT
Fri Oct 25 2002 14:40, Alexander Grischenko wrote to Evgeny Kassyanenko:
> непонятно, чем им запись не нравилась? Меня постоянно дергают новички,
Почему - понятно, чтобы новички не приучались использовать это
невыразительное средство ;)
В общем-то, IMHO, с самого начала, борландам надо было разрешать запись
в константы только в секции initialization.
В остальных случаях можно использовать более прямые средства, а в свое
оправдание могу лишь сказать, что пожертвовал формой ради краткости,
но, надеюсь, смыслу оно не повредило.
> var
> zeroVal :interger = 0;
А вот в локальные (где оно более полезно), AFAIK с D4.
> тут никакие галочки мешать не будут.
Будут, будут :) Глобальные - MD, останутся только классы/объекты.
Кстати, zeroVal и так нулем инициализируется.
С уважением, LVT
LT>> Кстати, zeroVal и так нулем инициализируется.
>> Hадеяться на то, что что-то где-то по умолчанию чем-то
>> инициализируется -
>> стремно вообще-то... Hа "брюки превращаются...." похоже ;))
LT> Вроде бы, не одни лишь надежды.
Ну а вдруг изменят? Есть проекты, что живут еще со времен D2-D3...
LT> D3 help.ariable declarations:
[Sorry, skipped]
Да нет, я не про это... Скорее общее правило "следи сам за инициализацией"
должно распространяться на все, что есть в программе.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
e-mail: to...@scm.com.ua
Leonid Troyanovsky <lv...@eco-pro.ru> пишет в
сообщении:3DB9902E...@eco-pro.ru...
> Я думаю, что в данном случае, все это лишь самоуспокоение.
Скажем так, "явное указание самому себе (а м.б. и другим)" что переменной
присвоено значение "0". Иначе - может "0", а может просто забыл присвоить.
> Т.е., после явной (неявной) инициализации нулем, вне зависимости от
содеянного
> компилятором, ответственность по использованию глобальной переменной
целиком
> лежит на совести программиста.
Дыкть, каждый сам себе...
> По мне лучше, чтобы было единообразие, т.е., либо везде, либо нигде.
Лучше всегда и везде.
> В случае же изменения политики партии, компилятор, IMHO, должен
по-крайней
> мере, выдать warning. А если не выдаст .. я его укушу :)
Надеюсь, что политика в этом не измениться.
Хотя в таком подходе есть и отрицательная сторона - маскировка ошибок.
А раньше, в случае ошибки, непроинициализированная переменная время от
времени приводило бы к AV и стал бы искать причину.
Как и еще одно новшество - D6 vs D5: D5 - не создал класс - улетел в AV.
А D6 продолжает выполнение. И AV в совершенно произвольном месте,
и далеко от ошибки.
Успехов,
Виктор
LT> Кстати, ничего страшного не вижу в том, что некий Integer не
LT> инициализирован 0 глобально. Использующие глобальные переменные, все
LT> равно, должны чувствовать себя параноиками, каждый раз перед их
LT> использованием спрашивая себя, какая неприятность случится в этот
LT> раз (шут.)
Я всегда подозревал, что я - параноик ;)))))
LT> Поэтому, я считаю, что по большому счету, право на глобальную жизнь
LT> имеют лишь списки, коллекции и др.
Особенно, если их создавать разрушать в блоках initialization/finalization.
LT> Надо полагать, что в подозрениях ты последователен и после каждого
LT> Create скурпулезно очищаешь все поля? ;)
Нет, у меня в конструкторах автозаполнение стоит ;)))
Просто опасение вызывает использование глобальных переменных где надо и где
не надо... Особое "веселье" вызывают одноименные глобальные переменные
(типизированные константы) в разных модулях. Мне как-то пришлось дописывать
большой проект, доставшийся по наследству от такого вот любителя
"глобальности" ;(
Victor V. Shaclein wrote:
LT> В случае же изменения политики партии, компилятор, IMHO, должен
LT> по-крайней мере, выдать warning.
> Надеюсь, что политика в этом не измениться.
> Хотя в таком подходе есть и отрицательная сторона - маскировка ошибок.
> А раньше, в случае ошибки, непроинициализированная переменная время от
> времени приводило бы к AV и стал бы искать причину.
Вот-вот, маскировка ошибок - повод для самоуспокоения ;)
> Как и еще одно новшество - D6 vs D5: D5 - не создал класс - улетел в AV.
> А D6 продолжает выполнение. И AV в совершенно произвольном месте,
> и далеко от ошибки.
Возможно, что изменилась "порция" выделяемой дельфийским менеджером памяти
или граница ее выравнивания, т.е. возникают AV, например, при обращении
к WndProc или иным методам уже реально нарушающим границу.
Sergey Gerasin wrote:
VP> var
VP> OldCol: Longint=-1; OldRow : Longint = -1;
VP> вместо const
VP> OldCol: Longint=-1; OldRow : Longint = -1;
> Если это сделано локально в функции - разница огромадная! Если менять
> значение етих (переменных|констант) в теле функции, то константы (которые
> типизированные) будут сохранять свои значения _между_ вызовами функции.
В исходном примере так оно и было, т.е. это локальные константы в методе формы.
Альтернативой этому рассматривались var в юните формы, но это тоже не до конца
правильно, т.к. вполне возможно, что этот метод захочется использовать и для
другого StringGrid (скажем, на другой форме) - отсюда возможны грабли.
Конечно, можно пытаться использовать TStringGrid.Tag для хранения пары Word,
но, все же, лучше сделать OldCol, OldRow полями своего класса TStringGrid.
Т.е., использование локальных типизированных констант, в данном случае,
препятствует повторному использованию кода.
VP> var
VP> OldCol: Longint=-1; OldRow : Longint = -1;
VP> вместо const
VP> OldCol: Longint=-1; OldRow : Longint = -1;
VP> Пусть переменые менянются, а уж константы(типизированные или нет)
VP> будут константами.
VP> Должно же в этом проклятом мире быть хоть что-то постоянным!!! :)))
Если это сделано локально в функции - разница огромадная! Если менять
значение етих (переменных|констант) в теле функции, то константы (которые
типизированные) будут сохранять свои значения _между_ вызовами функции.
Вообще, типизированные константы в Паскале, имхо, аналогичны статическим
переменным в сях... Или в плюсах - не помню, когда они там появились...
VP> Еще раз всем спасибо за отклики и помощь, но думаю тему пора закрыть
VP> или вынести ее за пределы данной эхи...
Ето точно, особенно в свете того, что вся эта инфа есть в справке Delphi.
--
С уважением, Сергей.
ser...@energomash.ru
ICQ: 63474652
Dmitry Beloshistov wrote:
..
> Выводы
> 1) не использовать глобальные переменные с одинаковыми именами
Мы же, вроде, хотели и вовсе от них отказаться.
Предлагаю ограничиться 4 первыми словами :)
> 2) выносить все глобальные переменные в отдельный модуль, "отвечающий"
> только за них
Да, такое даже отражено в FAQ Q-27. Но, та тема оставляет за бортом
многие возникающие вопросы, первый из которых должен ли этот модуль
содержать секцию var, и, если нет то где, собс-но, нам хранить
необходимые нам переменные. С константами, т.е. с "настоящими"
константами, вроде все ясно, т.е. можно, а вот с переменными..
> 3) рекомендуется давать вразумительные названия (BDNF_101_JHDF уж как-то
> дико звучит и я уже сам забыл, что же я тут зашифровал?-)))
Двумя руками - за.
> 4) при использовании типизированных констант - быть очень внимательным и по
> возможности работать с ними не напрямую, а через процедуры/функции - меньше
> вероятность ошибки (вот тут и подошли к тому, что лучше завести себе
> глобальный обьект для хранения данных (тот же TDataModule) и работать с его
> пропертями ;)
Думаю, что в свете новой политики партии для новых проектов всем требуется
$WRITEABLECONST OFF. Процедурный же доступ может нас обезопасить в случае
возврата простых, т.е. необъектных типов.
По поводу TDataModule думаю, что направление верное, но объект, IMHO,
несколько тяжеловат, скорее всего, в большинстве случаев нам не требуется
окно (например, для запросов через SendMessage).
Для оконных приложений класс главной формы кажется хорошим местом для
хранения всех необходимых приложению глобальных переменных.
Предположим, что все их мы будем хранить в приватном record, а
в public property вынесем все то, что потребуется другим частям
приложения. Описание свойств формы вынесем в отдельный (интерфейсный)
юнит, который могут подключать заинтересованные модули, а ссылку
они могут получить через Application.MainForm.
Остается разобраться с теми переменными, которые необходимы уже на
стадии initialization. В принципе, их можно было бы инициализировать
в dpr, но не создавая переменной, видимой в других модулях.
Это было б просто для своего наследника TApplication, но, честно
говоря, хотелось бы минимальных модификаций dpr, а еще лучше сделать
все в initialization главной формы (по-крайней мере для переменных,
необходимых главной форме).
--
С уважением, LVT.
Dmitry Beloshistov wrote:
> С другой стороны оглядываясь на множество вопросов "как узнать путь, откуда
> приложение запустилось?" и кучу ответов по поводу Application.ExeName и
> ExtractFilePath(ParamStr(0)) было бы удобно вынести что-то вроде:
> const StartPath:String='';
> и в секцию Initialization вписать StartPath:=ExtractFilePath(ParamStr(0))...
Тут, главное, что Application.ExeName существует, а изготовит ли кто
из него нужные константы и в каком месте - дело разработчика, нам же
интересно как обойтись без дополнительных глобальных var (т.е., помимо
существующих Application, Screen и т.п.).
> 1) чтобы обратиться к Application - нужен модуль Forms (нафига он для
> консольных утилит?)
Вот, для консольных утилит - вопрос требует отдельного рассмотрения.
Пока лишь утешимся тем, что в консольных утилитах не бывает (много) форм ;)
> В свете того, что логически запись:
> var GlobalVar:integer=0 и const GlobalConst:integer=0
> эквивалентны (в обе можно писать, обе могут участвовать в операциях и
> т.п.) - это мутный вопрос и скорее каждый в силу своих привычек должен для
> себя определить, что удобнее.
Нет, нет - использование типизированных констант мы уже осудили
(руководствуясь показанной нам генеральной линии :)
> Единственно, я бы ратовал за инициализацию -
> не нужно вспоминать, что подставиться по умолчанию,экономит время, визуально
> (имхо) легче воспринимается. А вообще - отдельный обьект лучше - можно
> написать метод LoadFromXXXX() и "легким движением руки" переинициализировать
> переменные (взять другой конфиг).
А я сейчас рискну пнуть инициализацию. Попробую сформулировать это так:
"Юнит формы не нуждается в секции инициализации/финализации", т.е все
необходимое форма может получить в OnCreate, Create или CreateWnd.
LT> требуется $WRITEABLECONST OFF.
> Умолчательно - да. В крайнем случае для отдельных мест вписать руками ON ;)
Ну, в initialization, если кто-то, все же, будет ее пользовать.
> А для консоли? Для Application - требуется Forms. Уж лучше смотреть в
> сторону отдельного класса-хранилища настроек - более универсально получиться
> +
> возможность "заточить" предка под метод хранения конфигурации
> (регистри/ини-файлы/свои конфиги).
Я, в общем-то, тоже не против объекта, просто вопрос кто его будет держать
и как/какой интерфейс ему придать.
> Я все больше склоняюсь к отдельному классу. В методе Create() или другом
> создаем/читаем/инициализируем все что надо, дальше работаем с пропертями...
> Все в отдельном модуле, подключаемом по необходимости.
> В Initilization - создаем обьект, в finalization - убиваем..
Пока мне представился вот такой вариант для оконных приложений:
------------------------------Project1.dpr------------------------------
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
UnitGlob in 'UnitGlob.pas';
{$R *.RES}
var
dummy: Pointer; // спасибо Borland'у
begin
Application.Initialize;
Application.CreateForm(TForm1, dummy);
Application.Run;
end.
------------------------------EOF Project1.dpr------------------------------
-----------------------------------UnitGlob.pas-----------------------------
unit UnitGlob;
interface
uses
Forms;
type
TMyApplication = class(TApplication)
private
FGlobalValue : Longint;
public {можно сделать и published, для обращения по имени }
property GlobalValue: Longint read FGlobalValue
write FGlobalValue;
{..}
end;
implementation
initialization
Application.Free;
Application := TMyApplication.Create(nil); // теперь оно наше
with TMyApplication(Application) do
begin
GlobalValue := 1;
{..}
end;
end.
-------------------------------EOF UnitGlob.pas-----------------------------
-------------------------------unit1.pas------------------------------------
..
// var Form1: TForm1 // мы от нее избавились
implementation
{$R *.DFM}
uses
UnitGlob; // нам потребуется декларация TMyApplication
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption := IntToStr(TMyApplication(Application).GlobalValue);
end;
end.
---------------------------EOF unit1.pas------------------------------------
LT>> Поэтому, я считаю, что по большому счету, право на глобальную жизнь
LT>> имеют лишь списки, коллекции и др.
LT> было бы интересно выработать некий программный документ, что-то
LT> вроде "Нет - глобальным переменным" (рабочее название). Туда могли
LT> бы войти убедительные примеры их преступной роли, а также
LT> рекомендации по тому, как можно (нужно) избегать их использования.
Согласен... Например такое:
Unit Unit_One;
.....
Const
MyGlobal:integer=12345;
и
Unit Unit_Two;
.....
Const
MyGlobal:integer=56789;
При использовании Unit_One и Unit_Two получаем:
1) какая из MyGlobal используется в выражении ABC:=MyGlobal (смотрим
постоянно в Uses)?
2) какая измениться при MyGlobal:=MyGlobal+123 (опять-таки - смотрим в
Uses)?
Ну и доп. возможные грабли, если Unit_XXXX использует и Unit_One и Unit_Two
и работает с обоими MyGlobal - начинает играть роль порядок подключения
модулей,
(во избежание - нужно обязательно использовать в качестве префикса имя
модуля).
Простая илюстрация:
Uses Unit_One,Unit_Two;
.....
ShowMessage(IntToStr(Unit_One.MyGlobal));
ShowMessage(IntToStr(Unit_Two.MyGlobal));
ShowMessage(IntToStr(MyGlobal));
MyGlobal:=1234;
ShowMessage(IntToStr(MyGlobal));
ShowMessage(IntToStr(Unit_One.MyGlobal));
ShowMessage(IntToStr(Unit_Two.MyGlobal));
.....
При операциях с MyGlobal в достаточно большом исходнике - верный путь
получить по лбу граблями. Причем компилятор никаких предупреждений не выдаст
и процесс поиска ошибки превращается в долгую рутину. Хуже того, при больших
ветвлениях и обилии математики - можем получить т.н. плавающую ошибку, когда
программа при сочетании определенных условий может выдавать абсолютно
неправильный результат.
Выводы:
1) не использовать глобальные переменные с одинаковыми именами
2) выносить все глобальные переменные в отдельный модуль, "отвечающий"
только за них
3) рекомендуется давать вразумительные названия (BDNF_101_JHDF уж как-то
дико звучит и я уже сам забыл, что же я тут зашифровал?-)))
4) при использовании типизированных констант - быть очень внимательным и по
возможности работать с ними не напрямую, а через процедуры/функции - меньше
вероятность ошибки (вот тут и подошли к тому, что лучше завести себе
глобальный обьект для хранения данных (тот же TDataModule) и работать с его
пропертями ;)
Мнение?
>> Выводы
>> 1) не использовать глобальные переменные с одинаковыми именами
LT> Мы же, вроде, хотели и вовсе от них отказаться.
LT> Предлагаю ограничиться 4 первыми словами :)
С другой стороны оглядываясь на множество вопросов "как узнать путь, откуда
приложение запустилось?" и кучу ответов по поводу Application.ExeName и
ExtractFilePath(ParamStr(0)) было бы удобно вынести что-то вроде:
const StartPath:String='';
и в секцию Initialization вписать StartPath:=ExtractFilePath(ParamStr(0))...
Сразу же оговорюсь, почему:
1) чтобы обратиться к Application - нужен модуль Forms (нафига он для
консольных утилит?)
2) функция/процедура будет выполняться каждый раз при вызове, что иногда не
очень-то нужно - лишние тормоза (сейчас меня помидорами начнут закидывать
владельцы супер-пупер быстрых процессоров ;))))
>> 2) выносить все глобальные переменные в отдельный модуль,
>> "отвечающий"
>> только за них
LT> Да, такое даже отражено в FAQ Q-27. Но, та тема оставляет за
LT> бортом многие возникающие вопросы, первый из которых должен ли
LT> этот модуль содержать секцию var, и, если нет то где, собс-но, нам
LT> хранить необходимые нам переменные.
В свете того, что логически запись:
var GlobalVar:integer=0 и const GlobalConst:integer=0
эквивалентны (в обе можно писать, обе могут участвовать в операциях и
т.п.) - это мутный вопрос и скорее каждый в силу своих привычек должен для
себя определить, что удобнее. Единственно, я бы ратовал за инициализацию -
не нужно вспоминать, что подставиться по умолчанию,экономит время, визуально
(имхо) легче воспринимается. А вообще - отдельный обьект лучше - можно
написать метод LoadFromXXXX() и "легким движением руки" переинициализировать
переменные (взять другой конфиг).
[Sorry, skipped]
>> 4) при использовании типизированных констант - быть очень
>> внимательным и по возможности работать с ними не напрямую, а через
>> процедуры/функции - меньше вероятность ошибки (вот тут и подошли к
>> тому, что лучше завести себе глобальный обьект для хранения данных
>> (тот же TDataModule) и работать с его пропертями ;)
LT> Думаю, что в свете новой политики партии для новых проектов всем
LT> требуется $WRITEABLECONST OFF.
Умолчательно - да. В крайнем случае для отдельных мест вписать руками ON ;)
[Sorry, skipped]
LT> По поводу TDataModule думаю, что направление верное, но объект, IMHO,
LT> несколько тяжеловат, скорее всего, в большинстве случаев нам не
LT> требуется окно (например, для запросов через SendMessage).
TDataModule - лишь как пример того, что уже есть. Я нисколько не возражаю
против написания своих обьектов для данных.
LT> Для оконных приложений класс главной формы кажется хорошим местом
[Sorry, skipped]
А для консоли? Для Application - требуется Forms. Уж лучше смотреть в
сторону отдельного класса-хранилища настроек - более универсально получиться
+
возможность "заточить" предка под метод хранения конфигурации
(регистри/ини-файлы/свои конфиги).
LT> Остается разобраться с теми переменными, которые необходимы уже на
LT> стадии initialization. В принципе, их можно было бы инициализировать
LT> в dpr, но не создавая переменной, видимой в других модулях.
Я все больше склоняюсь к отдельному классу. В методе Create() или другом
создаем/читаем/инициализируем все что надо, дальше работаем с пропертями...
Все в отдельном модуле, подключаемом по необходимости.
В Initilization - создаем обьект, в finalization - убиваем..
WBR, Dmitry Beloshistov AKA [-=BDS=-]
e-mail: to...@scm.com.ua
LT> Однако, и консольному приложению может быть полезен объект
LT> Application, который может предоставлять такие свойства как
LT> ExeName, Title и т.д., методы Terminate и др. Создавая
LT> специализированного наследника для
LT> TApplication, можно снабдить этот объект дополнительными
LT> полями/свойствами, необходимыми приложению в целом.
Согласен, но это ведет к увеличению обьема exe на несколько сотен Кб. С
учетом того,что консольные приложения - мелкие утилитки - не хотелось бы
такого...
LT> В чем же преимущество использование объекта TApplication, который
LT> будет доступен, все же, через (глобальную!) переменную Application?
LT> Прежде всего, это централизация хранения и управления доступом ко
LT> всем глобальным объектам, создаваемых в любых юнитах. Hапример, так
LT> гораздо проще разрешать конфликты имен, управлять порядком создания
LT> и разрушения необходимых глобальных объектов и т.д.
А в чем преимущество TApplication перед одним доп. глобальным обьектом, на
который также можно возложить те же задачи и при необходимости
инкапсулировать его в TApplication (твой метод).. Все же отдельный
глобальный обьект дает более гибкий подход. А конфликт имен легко обходится
именно обьектом, причем без разницы, TApplication это или еще какой.
Mon Oct 28 2002 10:25, Dmitry Beloshistov wrote to Leonid Troyanovsky:
LT> Однако, и консольному приложению может быть полезен объект
LT> Application, который может предоставлять такие свойства как
LT> ExeName, Title и т.д., методы Terminate и др. Создавая
LT> специализированного наследника для
LT> TApplication, можно снабдить этот объект дополнительными
LT> полями/свойствами, необходимыми приложению в целом.
> Согласен, но это ведет к увеличению обьема exe на несколько сотен Кб. С
> учетом того,что консольные приложения - мелкие утилитки - не хотелось бы
> такого...
Hе думаю, что намного - всю функцинальность TApplication оконных
приложений повторить не получится (у консоли многого просто нет).
Так, - 2-3 кб, зато будет что-то похожее на общий подход ;)
> А в чем преимущество TApplication перед одним доп. глобальным обьектом,
> на который также можно возложить те же задачи и при необходимости
> инкапсулировать его в TApplication (твой метод).. Все же отдельный
> глобальный обьект дает более гибкий подход. А конфликт имен легко
> обходится именно обьектом, причем без разницы, TApplication это или еще
> какой.
Для консолей, действительно, и то и другое необходимо создавать
и привязывать к существованию приложения, но, преимущество
консольного Application - в использовании по аналогии с оконным.
С уважением, LVT
>> 1) чтобы обратиться к Application - нужен модуль Forms (нафига он для
>> консольных утилит?)
LT> Вот, для консольных утилит - вопрос требует отдельного
LT> рассмотрения.
LT> Пока лишь утешимся тем, что в консольных утилитах не бывает
LT> (много) форм ;)
Хм... И констант/переменных там тоже много не бывает?-)) Как раз консольные
приложения отличаются меньшей "стройностью" (насколько я знаю)...
>> Уж лучше смотреть в сторону отдельного класса-хранилища настроек - более
>> универсально получиться +
[Sorry, skipped]
LT> Я, в общем-то, тоже не против объекта, просто вопрос кто его будет
LT> держать и как/какой интерфейс ему придать.
Можно что-то вроде:
type
TConstStorage=class
private
FGlobal:integer;
public
Constructor Create(........); virtual;
Procedure LoadSettings; virtual;
Procedure SaveSettings; virtual;
published
property Global:integer read FGlobal write FGlobal;
end;
var ConstStorage:TConstStorage;
.......
initialization
ConstStorage:=TConstStorage.Create(........);
finalization
ConstStorage.Free;
end;
>> Все в отдельном модуле, подключаемом по необходимости.
>> В Initilization - создаем обьект, в finalization - убиваем..
LT> Пока мне представился вот такой вариант для оконных приложений:
[Sorry, skipped]
Все-таки - потомок от TApplication, от чего хотели отказаться..
В моем варианте получим :
Uses ConstStorageUnit;
.......
Constructor TxxxxxClassOrForm.Create(..........)
begin
inherited;
xxxxxxClassOrFormVariable:=ConstStorage.xxxxProperty;
end;
И к тому же вполне применимо и для консольных приложений...
Т.е. без доп. замен/переопределений (что-то вроде обьекта Printer у
Borland)...
Да и понаплодить наследников от TConstStorage все же легче (более очевидный
путь, т.к. class TApplication в большинстве случаев остается за кадром и
многие новички о нем и не вспоминают (не говоря уже о попытках что-то
изменить), занятые формостроительством и компонентобросанием ;)
LT> Вот, для консольных утилит - вопрос требует отдельного рассмотрения.
Особенность консольных приложений в том, что они в меньшей степени
ориентированы на события, поэтому распределение объектов между юнитами
может проходить не так болезненно, как для оконных приложений.
Однако, и консольному приложению может быть полезен объект Application,
который может предоставлять такие свойства как ExeName, Title и т.д.,
методы Terminate и др. Создавая специализированного наследника для
TApplication, можно снабдить этот объект дополнительными полями/свойствами,
необходимыми приложению в целом.
В чем же преимущество использование объекта TApplication, который
будет доступен, все же, через (глобальную!) переменную Application?
Прежде всего, это централизация хранения и управления доступом
ко всем глобальным объектам, создаваемых в любых юнитах. Hапример,
так гораздо проще разрешать конфликты имен, управлять порядком создания
и разрушения необходимых глобальных объектов и т.д.
С уважением, LVT
LT>> Я, в общем-то, тоже не против объекта, просто вопрос кто его
LT>> будет держать и как/какой интерфейс ему придать.
>> Можно что-то вроде:
>> type
>> TConstStorage=class
LT> Можно, конечно, но это значит, что нам требуется еще одна
LT> глобальная переменная, что проливает воду на чужую мельницу.
Тогда давай определимся. Есть 2 метода уменьшения числа глобальных
переменных:
1) запихивать их в потомка от TApplication (твой)
2) делать 1 глобальный обьект для их хранения (мой)
Для 2) - более просто и более гибко но возникает проблема валидности. Но
если ввести доп. правило ничего не делать с этим обьектом а возложить все на
initialization/finalization, то проблему с валидностью можно также решить.
К тому же что мешает расширить главную форму приложения, к которой можно и
достучаться при необходимости и вопроса валидности тоже вроде не стоит (при
закрытии главной формы обычно и приложение закрывается)?
DB>> Все-таки - потомок от TApplication, от чего хотели отказаться..
LT> У Application два достоинства (есть, конечно, и недостатки):
LT> переменная уже существует при она тесно связана с приложением, т.е
LT> разрушение завершает приложение.
LT> Для других же переменных нам придется думать и о их валидности.
О валидности Screen и результата от ф-ции Printer часто не думают - к ним
просто обращаются...
В Destroy сделать Terminate, будет полный аналог TApplication-у в этом
вопросе.
Hо... "Меня терзают смутные сомнения" (С) А как избежать создания _второго_
экземпляра в обоих случаях?
--
With beast regard, Ole (not OLE!)
o...@fcs.dp.ua
Mon Oct 28 2002 13:24, Олег Милаш wrote to All:
> Hо... "Меня терзают смутные сомнения" (С) А как избежать создания
> _второго_ экземпляра в обоих случаях?
Тут, к сожалению, обычная картина - переменная одна, а объектов
может быть и несколько (вот она неприятность), т.е. плата за
глобальность. Хорошо еще то, что Run будет лишь один объект :)
С уважением, LVT
Mon Oct 28 2002 11:43, Dmitry Beloshistov wrote to Leonid Troyanovsky:
> Тогда давай определимся. Есть 2 метода уменьшения числа глобальных
> переменных:
> 1) запихивать их в потомка от TApplication (твой)
> 2) делать 1 глобальный обьект для их хранения (мой)
> Для 2) - более просто и более гибко но возникает проблема валидности. Hо
> если ввести доп. правило ничего не делать с этим обьектом а возложить все
> на initialization/finalization, то проблему с валидностью можно также
> решить.
Hу, как выяснилось, сами эти секции тоже можно покритиковать :)
> К тому же что мешает расширить главную форму приложения, к которой можно
> и достучаться при необходимости и вопроса валидности тоже вроде не стоит
> (при закрытии главной формы обычно и приложение закрывается)?
Класс формы - это само собой, т.е., все, переменные, использующиеся
в юните формы должны быть в его полях (за исключением, возможно,
"суперглобальных" - т.е., которые в Application.
LT> Для других же переменных нам придется думать и о их валидности.
> О валидности Screen и результата от ф-ции Printer часто не думают - к ним
> просто обращаются...
Воот. И, главное, что борланды и сами об этом не особо задумывались :)
С уважением, LVT
Mon Oct 28 2002 13:52, Dmitry Beloshistov wrote to Leonid Troyanovsky:
DB> О валидности Screen и результата от ф-ции Printer часто не думают
LT> Воот. И, главное, что борланды и сами об этом не особо задумывались
> Вот смотрю я на метод TApplication.Free и думаю - "может и себе его
> попользовать?-)))"...
Hу, его можно дополнить в наследнике, например:
if Assigned(MainForm) then MainForm.Close;
С уважением, LVT
Mon Oct 28 2002 14:50, Dmitry Beloshistov wrote to Олег Милаш:
ОМ> А как избежать создания_второго_ экземпляра в обоих случаях?
> if not Assigned(MyObj) then
Все равно, не спасает от создания второго экземпляра в случае,
если за Create случится MyObj := nil.
С уважением, LVT
Угумс. И я об этом. Получается, спасение утопающих... И чем это
_принципиально_ будет отличаться от переменных в отдельном модуле?
> >> Да и управлять обилием переменных - еще та задача. С обьектом -
> >> получим
> ОМ> хотя
> >> бы централизованное управление переменными.
>
> ОМ> Чем оно централизованней _единственного_ юнита с переменными, если
> ОМ> мы дали себе слово не применять глобальных переменных нигде более?
>
Я извиняюсь что вмешиваюсь, но ИМХО тут уже немножко переливание из пустого
в порожнее началось. Вот по этим четырем пунктам хочу сказать, например: ни
один из них НЕ описывает принципиального отличия объекта от отдельного
модуля _в контексте флейма_. ВСЕ это точно также справедливо и для модулей и
с такой же легкостью реализуется, а посему все четыре пункта НЕ являются
уникальными фичами объекта по отн. к модулю. Пришли вы к одним и тем же
белым скорлупкам с желтками, только в профиль и с разных сторон ;)
ИМХО.
А вопрос остается - "чем же все-таки оно централизованней" (с) :)
> 1) Меньше вероятность завести себе в другом модуле (все мы люди, все
что-то
> забываем) еще одну одноименную переменную со всеми вытекающими
Но ведь договорились, что все переменные в одном модуле?
> 2) Более легкое разрешение конфликта имен для обьекта - есть префикс АКА
имя
> обьекта при обращении к переменной.
...есть префикс АКА имя модуля при обращении к переменной ;)
Только зачем? Насколько я понял, флейм идет в струе 1 объект VS 1 модуль?
Или я недопонял - тогда извиняюсь.
> 3) Работа с пропертями более гибкая (GetXXX() / SetXXX() методы).
interface
function GetXxx: Tyyy;
procedure SetXxx(Value: Tyyy);
implementation
var
Xxx: Tyyy
function... ну понятно
? ;)
> 4) Можно иметь несколько обьектов, "настроенных" на разное кол-во данных и
> разные методы хранение конфигов и использовать только те, что нужно.
Насколько я понимаю, речь идет про полиморфизм? А перекрываемые
функции/процедуры (не методы объекта!) сюда никак не лепятся (возможно я не
прав, надо продумать)?
Хотя вот тут пожалуй самая интересная мысль, здесь наиболее трудно возразить
:)
Что касается упомянутой в другом письме многомодульности, плагинов и т.п. -
там как раз истина посередине, объекты-коллекции и другие разделяемые данные
сидят в одном модуле, доступном для всех составляющих (я обычно делаю такой
модуль в отдельной .bpl и компилирую приложение и плагины, занося ее в
список runtime-библиотек. красота...).
Все имхо, конечно, извиняюсь, что влез - таки интересно :)
P.S. Сам я сторонник объектов, но, повторюсь - истина где-то посередине,
каждый из вас по-своему прав :)
---
С уважением - Евгений Касьяненко,
Донецк, Украина
To understand recursion, we must first understand recursion
Уффф, целый день читаю...
> Да и управлять обилием переменных - еще та задача. С обьектом - получим
хотя
> бы централизованное управление переменными.
Чем оно централизованней _единственного_ юнита с переменными, если мы дали
себе слово не применять глобальных переменных нигде более?
--
> Кстати, а что будем делать, когда переменные лучше разделить по
подсистемам
> приложения? С обьектами - все понятно,с переменными - разбивать на
несколько
> модулей с опред. префиксом?
По подсистемам? Hу, это не совсем глобальные переменные. И потом, какие
несколько модулей? Вроде модифицированный тред за то, чтобы переменных много
не было.
>> Кстати, а что будем делать, когда переменные лучше разделить по
ОМ> подсистемам
>> приложения? С обьектами - все понятно,с переменными - разбивать на
ОМ> несколько
>> модулей с опред. префиксом?
ОМ> По подсистемам? Hу, это не совсем глобальные переменные. И потом,
ОМ> какие несколько модулей?
Приложение (оговорюсь - большое приложение, где десятки тысяч строк кода)
делится на несколько подсистем (интерфейс с БД, плагины и т.п.),которые
пишутся разными разработчиками (группами разработчиков)... Каждая из
подсистем реализуется не одним модулем. Вопрос - что будет удобнее - один
глобальный модуль переменных/констант или несколько меньших по размеру
модулей переменных, используемых каждый для своей подсистемы?
С этим согласен.
> Кроме того, создание нужного хранилища, скажем в конструкторе
Application
> делает ненужным отдельный доступ к внутренним объектам, включая и,
> например, их конструктор.
Мы все еще говорим о глобальных переменных ? Hе избыточно ли это именно для
подобных целей ?
Затронута интересная (для меня) тема. В одном проекте есть общий модуль, в
котором, в частности, и все глобальные переменные. Hо их не много по
сравнению с остальным, и манипулирование ими из этого модуля, в том числе и
глобальными функциями, затруднений не доставляло. Может быть, проект должен
быть каким-то особенным, чтобы переменных было много и потребовался
специальный механизм манипулирования ?
Hу, от невнимательности и нелинейности рук и обьекты не спасут. Да и имена
переменным лучше давать мнемонические.Хотя, да, вероятность ошибок
присутствует.
> 2) Более легкое разрешение конфликта имен для обьекта - есть префикс АКА
имя
> обьекта при обращении к переменной.
Имя_модуля.Переменная ?
> 3) Работа с пропертями более гибкая (GetXXX() / SetXXX() методы).
Глобальные функции GetXXX() / SetXXX() ?
> 4) Можно иметь несколько обьектов, "настроенных" на разное кол-во данных и
> разные методы хранение конфигов и использовать только те, что нужно.
Глобальные функции, реализующие то, что нужно ?
Правда, на модулях не реализуешь наследование, но оно надо, именно для
глобальных переменных ? Hужно ли тащить функциональность TObject-а для этого
случая ? И не избыточно ли это для не очень больших проектов ?
> EK> P.S. Сам я сторонник объектов, но, повторюсь - истина где-то
> EK> посередине, каждый из вас по-своему прав :)
>
> Жень, так оно в принципе и есть... Вот только писать функции (пусть и
> перегружаемые) для десятков переменных, как ты предлагаешь - более
> напряжно... В случае обьекта хоть Shift-Ctrl-C поможет ;)
Ну... во-первых, я не предлагаю - просто упомянул такую возможность, и то,
что в _контексте флейма_ это _принципиальной_ разницы не имеет. А
во-вторых - это уже вопрос облегчения/автоматизации рутинной работы, но
никак не грамотности проектирования, разве нет? ;) Ведь никто же (надеюсь)
не проектирует свой софт так, чтобы максимально подстроиться на всякие
облегчающие фишки IDE? ;-)
P.S. И если уж на то пошло, то написать эксперта, реализующего аналог class
completion для обычных интерфейсных объявлений (в смысле в секции
interface) - плевое дело, день работы... :-)
Tue Oct 29 2002 09:15, Dmitry Beloshistov wrote to Evgeny Kassyanenko:
EK> А во-вторых - это уже вопрос облегчения/автоматизации рутинной работы,
EK> но никак не грамотности проектирования, разве нет? ;)
> Я уже говорил, что в контексте флейма предлагаемый подход начинает
> работать для больших проектов и относится именно к грамотности
> проектирования... Для небольших поделок - возникает чувство
> тяжеловесности и гордость человека, заколотившего гвоздик для картины
> любимым микроскопом ;)
IMHO, еще должна быть присутствовать гордость за последовательность в
действиях, т.е., если мы взяли в руки микроскоп, то делаем им все,
по примеру древних мастеров - с помощью простого топора изготавливаем
некий шедевр ;) Hу, а, вообще, следует, наверное, ожидать облегчения
от возможности повторного использования кода.
> P.S. Кстати, кто сказал что микроскопом гвозди нельзя заколачивать?
> Hеудобно конечно, но можно ;)))))))
Можно, конечно, только на окуляр нужна накладка от танкового прицела.
Кстати, у меня появилась одна догадка по поводу преодоления конфликта
модулей и объектов. Т.е., этого конфликта и не будет, если юнит объекта
вовсе не содержит секцию var.
С уважением, LVT
Mon Oct 28 2002 18:46, Evgeny Kassyanenko wrote to Dmitry Beloshistov:
> в порожнее началось. Вот по этим четырем пунктам хочу сказать, например:
> ни один из них HЕ описывает принципиального отличия объекта от отдельного
> модуля _в контексте флейма_. ВСЕ это точно также справедливо и для
> модулей и
> с такой же легкостью реализуется, а посему все четыре пункта HЕ являются
> уникальными фичами объекта по отн. к модулю. Пришли вы к одним и тем же
> белым скорлупкам с желтками, только в профиль и с разных сторон ;)
Модуль, несмотря на сходный доступ, объектом не является, а хотелось
бы представить как должна выглядеть полностью объектная модель приложения.
При попытке двигаться снизу вверх - на уровень приложения, мы постоянно
натыкаемся на модульность, т.е. на отличный от объектно-ориентированного
способ повторного использования кода.
Т.е., вопрос можно поставить так: возможен ли компромисс между двумя
этими концепциями и как, собс-но, может выглядеть "по-настоящему"
объектно-ориентированный подход, по крайней мере, для оконных приложений.
> Hо ведь договорились, что все переменные в одном модуле?
Пока, IMHO, одного мнения нет, но проблема приобретает очертания :)
> P.S. Сам я сторонник объектов, но, повторюсь - истина где-то посередине,
> каждый из вас по-своему прав :)
Hу, а стороннику объектной модели не мешало бы предложить свое видение
решения проблемы преодоления объектами "модульных границ" ;)
С уважением, LVT
А можно пример грамотно написанного проекта, где глобальных переменных
гораздо более десятка ? Хотя бы на пальцах и для чего сие богатство.
Mon Oct 28 2002 17:48, Олег Милаш wrote to All:
DB> 3) Работа с пропертями более гибкая (GetXXX() / SetXXX() методы).
> Глобальные функции GetXXX() / SetXXX() ?
Глобальные функции имеют лишь один недостаток, они слишком глобальны -
это тоже препятствие на пути повторного использования кода.
Т.е., эти функции либо должны работать только с "простыми" типами данных,
либо уметь работать с _любыми_ типами объектов. Первое очень специфично,
а второе - сложно реализуемо.
Хотя, как показывает это обсуждение, есть общие задачи управления
приложением - инициализация общих данных, организация доступа к ним
из разных подсистем приложения и т.д., а значит, такое расширение
функциональности объекта "приложение", видимо, возможно.
DB> 4) Можно иметь несколько обьектов, "настроенных" на разное кол-во данных
DB> разные методы хранение конфигов и использовать только те, что нужно.
> Правда, на модулях не реализуешь наследование, но оно надо, именно для
> глобальных переменных ? Hужно ли тащить функциональность TObject-а для
> этого случая ? И не избыточно ли это для не очень больших проектов ?
Избыточность, IMHO, должна даже уменьшиться если удасться выделить общую
часть кода и прицепить его к уже существующему объекту, а специфические
части будут задаваться в его специализированных наследниках.
С уважением, LVT
Evgeny Kassyanenko wrote:
> А вопрос остается - "чем же все-таки оно централизованней" (с) :)
>
> > 1) Меньше вероятность завести себе в другом модуле (все мы люди, все
> > что-то
> > забываем) еще одну одноименную переменную со всеми вытекающими
>
> Hо ведь договорились, что все переменные в одном модуле?
А в случае коллективной разработки? У меня - все в одном модуле,
у тебя - все в другом.
> ...есть префикс АКА имя модуля при обращении к переменной ;)
> Только зачем? Hасколько я понял, флейм идет в струе 1 объект VS 1 модуль?
> Или я недопонял - тогда извиняюсь.
По-видимому, в случае одинаковых классов компилятор ругается, а в
случае одинаковых переменных - нет. Добавив еще один модуль, в
котором есть глобальная переменная, совпадающая с одной из моих,
я получаю труднонаходимую ошибку.
Виктор.
> > Hо ведь договорились, что все переменные в одном модуле?
>
> А в случае коллективной разработки? У меня - все в одном модуле,
> у тебя - все в другом.
Ну... все зависит от организации работы. Например, можно изначально
выработать какие-то соглашения, договориться, что должно быть в разделяемом
модуле, сделать его начальный (в идеале - он же и окончательный, но это
опять же зависит от изначальной грамотности проектирования) вариант - ну и
запихнуть в VSS или подобное, например. И для всего коллектива глобальные
данные лежат в одном месте, а также исключается возможность одновременного
изменения разделяемого модуля членами команды...
А если каждый городит глобальные хранилища кто где горазд - это уже не
коллективная разработка, а лоскутное одеяло, плюс практически 100%
вероятность ненужного дублирования. Тут хоть модули, хоть объекты - одна
беда...
> > ...есть префикс АКА имя модуля при обращении к переменной ;)
> > Только зачем? Hасколько я понял, флейм идет в струе 1 объект VS 1
модуль?
> > Или я недопонял - тогда извиняюсь.
>
> По-видимому, в случае одинаковых классов компилятор ругается, а в
> случае одинаковых переменных - нет. Добавив еще один модуль, в
> котором есть глобальная переменная, совпадающая с одной из моих,
> я получаю труднонаходимую ошибку.
Э... Разжуй.
Гм, это немного не тривиальный продукт, isn't it? Можно еще добавить
операционку, буде она написана. Hу, или оговорить, что классы
предпочтительней для проектов такого масштаба.
Hу а чем тут помогут классы?
... " http://gsoft.newmail.ru; http://www.nvkz.kuzbass.net/comics "
Evgeny Kassyanenko wrote:
> > По-видимому, в случае одинаковых классов компилятор ругается, а в
> > случае одинаковых переменных - нет. Добавив еще один модуль, в
> > котором есть глобальная переменная, совпадающая с одной из моих,
> > я получаю труднонаходимую ошибку.
>
> Э... Разжуй.
Это я не подумав сказал. Hа одноименные классы компилятор тоже не
ругается...
Хотя здесь меньше вероятность совпадения пары (имя класса, член
класса).
Виктор.
Всякие переменные типа ShortDateFormat. Да дофига.
MSL>> А разве в VCL глобальных переменных (сильно) больше десятка?
MSL>> Application, Screen, Printer, несколько ексепшенов. Всё?
AF> Всякие переменные типа ShortDateFormat. Да дофига.
Cлучайно старое письмо обнаружил в тему:
=====================================================================
From : Vitaly Fedoriv 2:4623/37.52 16 Апp 99 Пт 13:19
Subj : D3,D4.IDE.Code Completion - Hint
=====================================================================
Hello All.
Тут вот пpочитал забавний hint (для особо ленивых ;)) :
Обьявляем свои глобальные пеpеменные скопом таким обpазом:
===
Type
TMyGlobals = Record
IsSelected : Boolean;
UserName : String;
DBName : String;
RecordNum : Integer;
Status : Byte;
end;
Followed of course by a variable of that type.
Var
Global : TMyGlobals;
===
и потом пpи написании где нибудь в пpоге Globals. наслаждаемся появлением
списка с их пеpечислением.
Пpи куче глобальных пеpеменных (что, конечно, не есть гут, но иногда полезно)
жутко экономит вpемя.
Vitaly
===============================================================
... http://ichip.rbcmail.ru ... mailto: ichip(a)rbcmail.ru