Импорт модулей
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.08.05 07:11
Оценка: :))
Недавно я поднимал вопрос "Модульная загадка про константу"
Автор: Сергей Губанов
Дата: 01.07.05
о странном способе импорта модулей принятом в дотнете (конкретно там речь шла только об импорте констант, но на самом деле, тоже самое можно сказать об импорте любых объектов). Я недоумевал почему в дотнете с этим делом все так плохо, в то время как в оберонах с этим же делом все обстоит хорошо. Вчера, прочитав следующий материал:

Compiler Construction — The Art of Niklaus Wirth
Hanspeter Mossenbock
http://www.ssw.uni-linz.ac.at/Research/Papers/Moe00b.html

понимание наконец-то было достигнуто.

Уникальный идентификатор версии объекта

Оказывается в оберонах каждый экспортируемый модулем объект помечается своим собственным уникальным идентификатором (можете называть его как пожелаете — номер версии, подпись и т.п.). То есть не весь модуль целиком имеет один единственный уникальный идентификатор версии модуля, а каждый экспортируемый этим модулем объект имеет свой автоматически генерируемый персональный уникальный идентификатор версии.

Например, пусть модуль M экспортирует две константы M.c1 = 1 и M.c2 = 2. Каждая из этих констант будет снабжена своим собственным уникальным идентификатором версии. Допустим, теперь есть два модуля X и Y импортирующих модуль M (т. е. являющихся его клиентами), один из которых — X пусть использует только константу M.c1 = 1, а другой — Y пусть использует только константу M.c2 = 2. Теперь мы внесли изменение в модуль M, а именно изменили значение первой константы на другое, пусть теперь M.c1 = 0. Что будет? Надо ли перекомпилировать все модули-клиенты модуля M? Нет, все — не надо. Надо перекомпилировать только те модули-клиенты, которые использовали M.c1 = 1. При попытке запустить на исполнение модуль X загрузчик/линковщик сообщит об ошибке импорта константы M.c1 в модуле X, он просто сравнит версию этой константы с версией этой же константы хранимой в скомпилированном модуле X. То есть модуль X надо перекомпилировать. Но модуль Y будет исполняться как ни вчем ни бывало, ведь он не использует константу M.c1, его перекомпилировать не надо. Сказанное относится не только к константам, но и ко всем остальным экспортируемым модулем объектам.


На самом деле на этом приключения с экспортом-импортом не заканчивается. Есть еще один вопрос —

Цепочка импорта

Что если один модуль импортирует другой, а тот, в свою очередь, импортирует третий модуль, причем так, что первый модуль неявно его использует. В дотнете, оказывается надо добавить в список ссылок сборки и тот модуль тоже! Иначе получим вот такую ругань от компилятора:

***.dll Referenced class '***' has base class or interface '***' defined in an assembly that is not referenced. You must add a reference to assembly '***'.

То есть в дотнете в список импортируемых модулей должны быть включены все нужные модули, затем все модули нужные нужным модулям и рекурсивно так далее. В оберонах этого делать не нужно. В оберонах, если один модуль импортирует какие-то объекты из другого модуля, то информация о них (вместе с их номерами версий) просто копируется в его символьный файл. Импортировал он константу, вот только эта константа и будет добавлена. Ни откуда не следует, что размер символьных файлов по ходу цепочки будет становится все больше и больше. Ничего подобного, он может, наоборот, становится все меньше и меньше. Все зависит от того что будет экспортировано дальше, а что останется инкапсулированным. На самом деле символьные файлы на столько малы, что как было замечено Мёсенбёком, зачастую читаются с диска всего одной операцией чтения. Допустим теперь есть несколько модулей импортировавших один и тот же объект (из одного и того же модуля естественно) т.е. у каждого из них есть копия информации о том объекте. Ничего страшного — загрузчик/линковщик сверит версии копий информации об этом объекте и в зависимости от результата либо загрузит+слинкует модули либо выдаст сообщение об ошибке импорта.




P. S. Ханспетер Мёссенбёк – соавтор Н.Вирта по языку Оберон-2
Re: Импорт модулей
От: Oyster Украина https://github.com/devoyster
Дата: 12.08.05 07:25
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Оказывается в оберонах каждый экспортируемый модулем объект помечается своим собственным уникальным идентификатором (можете называть его как пожелаете — номер версии, подпись и т.п.). То есть не весь модуль целиком имеет один единственный уникальный идентификатор версии модуля, а каждый экспортируемый этим модулем объект имеет свой автоматически генерируемый персональный уникальный идентификатор версии.


Очень интересно, по какому алгоритму уникальные идентификаторы объектов меняются. Я так понял, идентификатор изменяется при перекомпиляции в случае, если объект изменился относительно последней скомпилированной версии модуля?
Re[2]: Импорт модулей
От: Трурль  
Дата: 12.08.05 07:45
Оценка: 19 (2)
Здравствуйте, Oyster, Вы писали:

O>Очень интересно, по какому алгоритму уникальные идентификаторы объектов меняются. Я так понял, идентификатор изменяется при перекомпиляции в случае, если объект изменился относительно последней скомпилированной версии модуля?


Идентификатор (fingerprint) объекта вычисляется при компиляции как "контольная сумма" из его определения.
Re[2]: Импорт модулей
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.08.05 07:47
Оценка:
Здравствуйте, Oyster, Вы писали:

O>Очень интересно, по какому алгоритму уникальные идентификаторы объектов меняются. Я так понял, идентификатор изменяется при перекомпиляции в случае, если объект изменился относительно последней скомпилированной версии модуля?


Этот вопрос меня тоже интересует. Вообще, ответ изложен у, как я понял, автора этого метода в его диссертации:

Regis Creiler "Separate Compilation and Module Extension". ETH dissertation 1994

осталось только ее раздобыть.

Второй способ найти ответ заключается в том чтобы покопаться в исходниках, например, Блэкбокса.
Re[3]: Импорт модулей
От: stalcer Россия  
Дата: 12.08.05 08:20
Оценка: +1
Здравствуйте, Трурль, Вы писали:

Т>Идентификатор (fingerprint) объекта вычисляется при компиляции как "контольная сумма" из его определения.


Тогда теоретически два разных определения объекта могут иметь одну и ту же контрольную сумму, со всеми вытекающими последствиями.
http://www.lmdinnovative.com (LMD Design Pack)
Re[3]: Импорт модулей
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.08.05 08:55
Оценка:
Т>Идентификатор (fingerprint) объекта вычисляется при компиляции как "контольная сумма" из его определения.

Кстати, для просто экспортируемых числовых констант в качестве finger-print-а естественно использовать ее собственное числовое значение.
Re[4]: Импорт модулей
От: Кодёнок  
Дата: 12.08.05 08:57
Оценка:
Здравствуйте, stalcer, Вы писали:

Т>>Идентификатор (fingerprint) объекта вычисляется при компиляции как "контольная сумма" из его определения.

S>Тогда теоретически два разных определения объекта могут иметь одну и ту же контрольную сумму, со всеми вытекающими последствиями.

Контрольная сумма в каком-либо секторе твоего винта может соответствовать разным данным. Тогда теоретически твои данные могут попортиться так, что контрольная сумма останется той же, со всеми вытекающими последствиями.
Re[5]: Импорт модулей
От: stalcer Россия  
Дата: 12.08.05 09:05
Оценка:
Здравствуйте, Кодёнок, Вы писали:

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


Сравнил, блин.

Если я на винте вообще уберу эту контрольную сумму, то все будет по прежнему работать, так как это только дополнительная мера предосторожности. А в случае версий объектов, это, извините, часть основного алгоритма.
http://www.lmdinnovative.com (LMD Design Pack)
Re[6]: Импорт модулей
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.08.05 09:11
Оценка:
Здравствуйте, stalcer, Вы писали:

S>Если я на винте вообще уберу эту контрольную сумму, то все будет по прежнему работать, так как это только дополнительная мера предосторожности. А в случае версий объектов, это, извините, часть основного алгоритма.


Надо ту диссертацию раздобыть и прочитать, а то так это гадание на кофейной гуще.
Re[6]: Импорт модулей
От: Дарней Россия  
Дата: 12.08.05 09:25
Оценка:
Здравствуйте, stalcer, Вы писали:

S>Если я на винте вообще уберу эту контрольную сумму, то все будет по прежнему работать, так как это только дополнительная мера предосторожности. А в случае версий объектов, это, извините, часть основного алгоритма.


MD5 — это тоже часть основного алгоритма цифровой подписи. И хотя хэш-функция может быть одинаковой для разных документов, это никому не мешает.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re: Импорт модулей
От: Дарней Россия  
Дата: 12.08.05 09:34
Оценка: 1 (1) +1
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Оказывается в оберонах каждый экспортируемый модулем объект помечается своим собственным уникальным идентификатором (можете называть его как пожелаете — номер версии, подпись и т.п.). То есть не весь модуль целиком имеет один единственный уникальный идентификатор версии модуля, а каждый экспортируемый этим модулем объект имеет свой автоматически генерируемый персональный уникальный идентификатор версии.


Если код самого класса не изменился, то это не значит, что не изменилось поведение этого класса. Потому что он зависит от других классов, которые определены в этом и/или других модулях, которые могли измениться независимо от него.
Модульная организация в .NET может дать гарантию, что программа будет использовать точно ту версию класса (и классов, от которых он зависит), с которой она была скомпилирована. Модульная организация оберонов такой гарантии не дает.
И что мы имеем в сухом остатке? Очередная война с ветряными мельницами.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[2]: Импорт модулей
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.08.05 09:56
Оценка:
Здравствуйте, Дарней, Вы писали:

Д>Если код самого класса не изменился, то это не значит, что не изменилось поведение этого класса. Потому что он зависит от других классов, которые определены в этом и/или других модулях, которые могли измениться независимо от него.


Смотрите пункт про цепочку импорта.

Д>Модульная организация в .NET может дать гарантию, что программа будет использовать точно ту версию класса (и классов, от которых он зависит), с которой она была скомпилирована. Модульная организация оберонов такой гарантии не дает.


Всё наоборот. В оберонах это гарантируется автоматически, а .NET ни каких гарантий не дает — тут программист сам должен обо всем не забыть позаботится. Он должен ручками менять номер версии всего модуля при этом обрекая все остальные модули-клиенты на перекомпиляцию даже если фактически они в ней и не нуждались. В доказательство этого я приводил пример не то что для классов, а даже для более простой вещи — для экспорта двух констант, одна из которох в последствии меняется. Для классов можете проверить это самостоятельно.
Re[2]: Импорт модулей
От: stalcer Россия  
Дата: 12.08.05 09:57
Оценка:
Здравствуйте, Дарней, Вы писали:

Д>Если код самого класса не изменился, то это не значит, что не изменилось поведение этого класса. Потому что он зависит от других классов, которые определены в этом и/или других модулях, которые могли измениться независимо от него.


В некоторых случаях как раз такое поведение и нужно. Для того, чтобы перекомпилировать как можно меньше, а значит — быстрее.
http://www.lmdinnovative.com (LMD Design Pack)
Re: Импорт модулей
От: stalcer Россия  
Дата: 12.08.05 09:57
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

А вроде в предадущем топике речь шла о том, что когда константа меняется, то ничего перекомпилиловать не нужно и все правильно работает.
А тут получается, что все-таки нужно?
http://www.lmdinnovative.com (LMD Design Pack)
Re[3]: Импорт модулей
От: Дарней Россия  
Дата: 12.08.05 10:06
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Смотрите пункт про цепочку импорта.


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

СГ>Он должен ручками менять номер версии всего модуля при этом обрекая все остальные модули-клиенты на перекомпиляцию даже если фактически они в ней и не нуждались. В доказательство этого я приводил пример не то что для классов, а даже для более простой вещи — для экспорта двух констант, одна из которох в последствии меняется. Для классов можете проверить это самостоятельно.


Отделим мух от котлет. Во первых, номер версии сборки меняется автоматически.
Во вторых — эти перекомпиляции не лишние. На текущем уровне развития систем разработки им не хватает интеллектуальности, чтобы определить, что "эта версия кода ведет себя точно так же, как предыдущая". Поэтому лучше перестраховаться, чем потом наступить на грабли.
И в третьих — если тебе так уж приспичило использовать отдельную сборку с константой, просто сделай ее static readonly, а не const. Хотя про это уже раз десять говорили, кажется.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[3]: Импорт модулей
От: Дарней Россия  
Дата: 12.08.05 10:08
Оценка:
Здравствуйте, stalcer, Вы писали:

S>В некоторых случаях как раз такое поведение и нужно. Для того, чтобы перекомпилировать как можно меньше, а значит — быстрее.


Это некритично. Если народ мирится со скоростью работы приплюснутого препроцессора, то уж лишние перекомпиляции в .NET точно переживет.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[2]: Импорт модулей
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.08.05 10:14
Оценка:
Здравствуйте, stalcer, Вы писали:

S>А вроде в предадущем топике речь шла о том, что когда константа меняется, то ничего перекомпилиловать не нужно и все правильно работает.

S>А тут получается, что все-таки нужно?

Да нет, это была фантазия. Дескать, а вот бы было бы так чтобы не надо было перекомпилировать модули самому, вот кайфно бы тогда стало. То есть теоретически, если компилировать сами исходники (пусть даже на промежуточном компактном языке) все перед каждым запуском (отказаться от заранее скомпилированных в машинные коды бинарных модулей), то вроде такого можно было бы добиться.
Re[4]: Импорт модулей
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.08.05 10:20
Оценка:
Здравствуйте, Дарней, Вы писали:

Д>Я не вижу там ничего про рекурсивную проверку версий всех классов, от которых зависит интересующий нас класс. Но даже такой проверки недостаточно, поскольку зависимости могут быть косвенными — через разделяемые данные, например.


Рекурсивная проверка и не нужна. Читайте внимательнее пункт "6 Separate Compilation".

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


У оберонов на это элементарное дело ума хватает, а у дотнета нет.

Д>И в третьих — если тебе так уж приспичило использовать отдельную сборку с константой, просто сделай ее static readonly, а не const. Хотя про это уже раз десять говорили, кажется.


Константы — это только для примера, вместо них можно было бы рассмотреть что угодно другое.
Re[5]: Импорт модулей
От: Курилка Россия http://kirya.narod.ru/
Дата: 12.08.05 10:25
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Здравствуйте, Дарней, Вы писали:

Д>>И в третьих — если тебе так уж приспичило использовать отдельную сборку с константой, просто сделай ее static readonly, а не const. Хотя про это уже раз десять говорили, кажется.

СГ>Константы — это только для примера, вместо них можно было бы рассмотреть что угодно другое.


Что конкретно?
Не надо кидаться фразами про "что угодно" если фактами не располагаешь, я думаю...
Re[5]: Импорт модулей
От: Дарней Россия  
Дата: 12.08.05 10:26
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Рекурсивная проверка и не нужна. Читайте внимательнее пункт "6 Separate Compilation".


Правда не нужна? Наверно, в программах на обероне функциональность каждого класса не зависит от других классов никаким образом.

СГ>У оберонов на это элементарное дело ума хватает, а у дотнета нет.


Я пока что заметил, что им хватает ума только на раскладывание тщательно замаскированных граблей.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.