Re[4]: Связанные с типом процедуры должны быть виртуальными
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 10.11.04 14:52
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Сергей ты намеренно приводишь не корректные примеры? Ты знаешь разницу между "примитивными" типами (они же value-типы) и классами "обычными?

К>Если да (на что я очень надеюсь), то посмотри в исходное сообщение своё — что там объектом было? Класс или целые числи или что-либо подобное?

Смотрим внимательно:
DEFINITION Integers;

    IMPORT Files;

    TYPE
        Integer = POINTER TO IntegerDesc;
    ...

Есть какой-то скрытый (инкапсулированный, приватный) тип под названием IntegerDesc и есть (публичный) экспортируемый тип Integer, который нужен для работы с целыми числами ПРОИЗВОЛЬНО БОЛЬШОГО размера. Это не примитивный тип. Тем не менее, у этого типа нет ни одного метода. Есть только "внешние" простые процедуры. Например,
PROCEDURE GCD (x, y: Integer): Integer;


Чего такого некорректного-то по сравнению со строками предложенными Клюевым?
Re[3]: Связанные с типом процедуры должны быть виртуальными
От: Kluev  
Дата: 10.11.04 14:53
Оценка: 6 (1)
Здравствуйте, Сергей Губанов, Вы писали:

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


K>>Например возьмем такой полезный класс string, который юзается повсеместно и должен быть удобным.


СГ>1) Зачем строке иметь виртуальный метод? Тип строки описывается один раз и навсегда, зачем его потом расширять?


Хорошо перейдем от абстрактных примеров к реальным. Вот к примеру интерфейс IBinaryStream

struct IBinaryStream
{
    virtual uint    read( void *buf, uint size )            = 0;
    virtual void    write( const void *buf, uint size )    = 0;

public: // хелперы
    template <class T> inline void 
        get( T value )
    {
        read( &value, sizeof(T) );
    }

    template <class T> inline void
        get( T ary[], uint n )
    {
        read( ary, sizeof(T) * n );
    }

    template <class T> inline void 
        put( const T value )
    {
        write( &value, sizeof(T) );
    }

    template <class T> inline void
        put( T ary[], uint n )
    {
        write( ary, sizeof(T) * n );
    }

};

void usaem_strim( IBinaryStream &stm, int a, double b, int c[], uint c_size )
{
    stm.get( a );
    stm.get( b );
    stm.put( c, c_size );
    stm.put( 10UL );
    // удобно однако!
}

// теперь в твоем стиле через процедуры:
void usaem_strim( IBinaryStream &stm, int a, double b, int c[], uint c_size )
{
    IBinaryStream_get( stm, a );
    IBinaryStream_get( stm, b );
    IBinaryStream_put( stm, c, c_size );
    IBinaryStream_put( stm, 10UL );
    // и к чему нам этот геморой на ровном месте?
}
Re[5]: Связанные с типом процедуры должны быть виртуальными
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.11.04 14:56
Оценка:
Здравствуйте, Alxndr, Вы писали:

A>Здравствуйте, Курилка, Вы писали:


К>>Скажи мне, где в Java, к примеру, есть модули?


A>Прошу прощения, по-моему, package'ы в Java выполняют именно функцию модулей.

A>Разве нет?

Модуль модулю рознь
Обероновским модулем не является (может быть Сергей меня поправит, если я вру...)
Re[6]: Связанные с типом процедуры должны быть виртуальными
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 10.11.04 15:07
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Здравствуйте, Alxndr, Вы писали:


A>>Здравствуйте, Курилка, Вы писали:


К>>>Скажи мне, где в Java, к примеру, есть модули?


A>>Прошу прощения, по-моему, package'ы в Java выполняют именно функцию модулей.

A>>Разве нет?

К>Модуль модулю рознь

К>Обероновским модулем не является (может быть Сергей меня поправит, если я вру...)

Да я в Java не так сильно разбираюсь... Но на сколько я понимаю, единицей исполнения, единицей расширения системы и единицей компиляции в Java кажется является файл с классом, а не пакет. Если так, то значит пакет — не модуль.
Re[4]: Связанные с типом процедуры должны быть виртуальными
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 10.11.04 15:16
Оценка:
Здравствуйте, Kluev, Вы писали:

K>Хорошо перейдем от абстрактных примеров к реальным. Вот к примеру интерфейс IBinaryStream

...
K> // и к чему нам этот геморой на ровном месте?

Я конечно понимаю, что писанины получается больше. Вместо кода:
  stm.ReadInteger(a);

надо писать код:
  Streams.ReadInteger(stm, a);

однако никакого гемороя, признаться, в этом не вижу. Ну и что такого-то, что чуток (на 1 слово — "Streams.") побольше написать? По существу замечания будут или нет?
Re[12]: Связанные с типом процедуры должны быть виртуальными
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 10.11.04 15:20
Оценка:
Здравствуйте, Курилка, Вы писали:

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


А вот, интересно, с точки зрения предметной области такие термины как class, private, protected, property get/set, случайно не являются искусственными понятиями?
Re[5]: Связанные с типом процедуры должны быть виртуальными
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.11.04 15:20
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

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


К>>Сергей ты намеренно приводишь не корректные примеры? Ты знаешь разницу между "примитивными" типами (они же value-типы) и классами "обычными?

К>>Если да (на что я очень надеюсь), то посмотри в исходное сообщение своё — что там объектом было? Класс или целые числи или что-либо подобное?

СГ>Смотрим внимательно:

СГ>
СГ>DEFINITION Integers;

СГ>    IMPORT Files;

СГ>    TYPE
СГ>        Integer = POINTER TO IntegerDesc;
СГ>    ...
СГ>

СГ>Есть какой-то скрытый (инкапсулированный, приватный) тип под названием IntegerDesc и есть (публичный) экспортируемый тип Integer, который нужен для работы с целыми числами ПРОИЗВОЛЬНО БОЛЬШОГО размера. Это не примитивный тип. Тем не менее, у этого типа нет ни одного метода. Есть только "внешние" простые процедуры. Например,
СГ>
СГ>PROCEDURE GCD (x, y: Integer): Integer;
СГ>


СГ>Чего такого некорректного-то по сравнению со строками предложенными Клюевым?


Вопрос — что есть тут Integer? Примитивный тип, аля Int32? Или же имя класса? Как они будут соотноситься и т.п.?
Имхо некорректный пример с недостаточными комментариями...
Re[13]: Связанные с типом процедуры должны быть виртуальными
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.11.04 15:31
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

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


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


СГ>А вот, интересно, с точки зрения предметной области такие термины как class, private, protected, property get/set, случайно не являются искусственными понятиями?


Имхо нет, ес-но в сфере рассмотрения предметной области сквозь призму ООП (которая гораздо ближе к человеческим понятиям, чем какой-то абстрактный "модуль")
Re[6]: Связанные с типом процедуры должны быть виртуальными
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 10.11.04 15:42
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Вопрос — что есть тут Integer? Примитивный тип, аля Int32? Или же имя класса? Как они будут соотноситься и т.п.?


Примитивный целочисленный тип пишется заглавными буквами INTEGER, а класс представляющий целые числа произвольно большого размера обозначени идентификатором Integer (первая буква заглавная, остальные маленькие)
DEFINITION Integers;

    IMPORT Files;

    TYPE
        Integer = POINTER TO IntegerDesc;
    ...

Класс IntegerDesc — не экспортируется модулем Integers, и поэтому в его интерфейсе не показан. На самом деле, если раздобыть исходник модуля Integers (у меня нет исходника), то в нем можно будет увидеть предположительно следующую реализацию класса IntegerDesc:
TYPE
  IntegerDesc = LIMITED RECORD
    (* поля данных представляющие целое число неограниченного размера *)
  END;
Re[7]: Связанные с типом процедуры должны быть виртуальными
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.11.04 15:48
Оценка: 2 (2) +1
Здравствуйте, Сергей Губанов, Вы писали:

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


К>>Вопрос — что есть тут Integer? Примитивный тип, аля Int32? Или же имя класса? Как они будут соотноситься и т.п.?


СГ>Примитивный целочисленный тип пишется заглавными буквами INTEGER, а класс представляющий целые числа произвольно большого размера обозначени идентификатором Integer (первая буква заглавная, остальные маленькие)


Вот ещё один супераргумент в пользу Вирта
Ты не думаешь, что если к каждой программе нужно писать далеко не 1 абзац комментариев, то это не есть хорошо? Просто есть некоторые вещи, которые уже особенно сильно не обсуждаются, ибо все принимают их "по дефолту", так вот встроенные типы БОЛЬШИМИ буквами писать имхо — маразм
Re[5]: Связанные с типом процедуры должны быть виртуальными
От: Зверёк Харьковский  
Дата: 10.11.04 15:49
Оценка: 1 (1) +3
Здравствуйте, Сергей Губанов, Вы писали:

СГ>однако никакого гемороя, признаться, в этом не вижу. Ну и что такого-то, что чуток (на 1 слово — "Streams.") побольше написать? По существу замечания будут или нет?

Это запросто! Недостаток твоего подхода — надо лишнее слово написать.
А преимущество? Ну хоть одно? Ну маааааалюююююююсенькое....
сам слушаю и вам рекомендую: в тишине сижу
FAQ — це мiй ай-кью!
Re[3]: Связанные с типом процедуры должны быть виртуальными
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.11.04 15:51
Оценка: +1
Здравствуйте, Сергей Губанов, Вы писали:

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


K>>Например возьмем такой полезный класс string, который юзается повсеместно и должен быть удобным.


СГ>1) Зачем строке иметь виртуальный метод? Тип строки описывается один раз и навсегда, зачем его потом расширять?


СГ>2) А строки, вообще-то, нехорошо в качестве примера приводить, так как работа со строками обычно встроена в сам язык программирования... Давайте лучше вместо строк рассмотрим тип целых чисел произвольного размера. У них тоже нет ни одного виртуального метода — зачем он им?


СГ>
//поскипано к чертям
СГ>


Пример у тебя не корректный ибо часть процедур не есть операции собственно класса "целое", а некоторые я бы в нём оставил (e.g. ConvertToString, только я бы убрал первый параметр, ибо он смысла не несёт, если мы операцию к известному объекту применяем)
Re[5]: Связанные с типом процедуры должны быть виртуальными
От: Kluev  
Дата: 10.11.04 15:51
Оценка: 16 (2)
Здравствуйте, Сергей Губанов, Вы писали:

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


K>>Хорошо перейдем от абстрактных примеров к реальным. Вот к примеру интерфейс IBinaryStream

СГ>...
K>> // и к чему нам этот геморой на ровном месте?

СГ>Я конечно понимаю, что писанины получается больше. Вместо кода:

СГ>
СГ>  stm.ReadInteger(a);
СГ>

СГ>надо писать код:
СГ>
СГ>  Streams.ReadInteger(stm, a);
СГ>

СГ>однако никакого гемороя, признаться, в этом не вижу. Ну и что такого-то, что чуток (на 1 слово — "Streams.") побольше написать? По существу замечания будут или нет?

Ага всего на одно слово больше.... почти в каждой строчке кода.
К тому же такой подход нарушает инкапуляцию. С какой это стати buffer_read находится в классе, а int_read уже глобальная процедура в модуле? Ничего кроме путаницы это не даст.

ИМХО это просто примитивизм, ктоторый пытаются протолкнуть как простоту. Если уж так хочется отличать виртуальную функцию от невиртуалной в классах то надо делать так, как я всегда делаю:

struct IBinaryStream
{
protected: // зашишенная виртуальная функция (только для наследования)
   virtual void IBinaryStream$read( void *buf, uint size ) = 0;

public: // хелпер для вызова
   void read( void *buf, uint size ) { IBinaryStream$read(buf,size); }
};

// В классе наследнике от IBinaryStream
class MyClass : public IBinaryStream
{
protected:
// видно что функция переопределена и видно из какого класса ноги растут:
  void IBinaryStream$read( void *buf, uint size ); 

};

// Даже если наследование углубилось и не видно что класс занаследован от IBinaryStream:
class AnotherClass : public MyClass
{
protected:
// все равно видно что функция переопределана и видно из какого класса.
  void IBinaryStream$read( void *buf, uint size ); 

  void MyClass$foo(); // здесь тоже все понятно без слов.
};

// А юзается это дело через хелпер:
void test( AnotherClass &ac )
{
   int x;
   ac.read( &x, sizeof(x) ); // транслируется в IBinaryStream$read
}


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

А то что предлагается в обероне так это просто курам на смех. Оберону надо всю кровь сменить и все органы пересадить (начиная с БЕГИН,ЭНД,ПРОЦЕ-ДУРА), тогда глядишь на него и будут смотреть программеры. А так его имхо юзают люди которые не смогли с паскаля слезть, как говориться старую собаку не обучишь новым штукам.
Re[6]: Связанные с типом процедуры должны быть виртуальными
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.11.04 16:16
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

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


СГ>>однако никакого гемороя, признаться, в этом не вижу. Ну и что такого-то, что чуток (на 1 слово — "Streams.") побольше написать? По существу замечания будут или нет?

ЗХ>Это запросто! Недостаток твоего подхода — надо лишнее слово написать.
ЗХ>А преимущество? Ну хоть одно? Ну маааааалюююююююсенькое....

Ну и ещё я бы добавил, что "обычный вариант стройнее, т.к. там выделяется что мы именно в стрим пишем, хотя это не такой уж и хороший пример (в отл., например, от операций с геом. фигурами и т.п.)
Re[13]: Связанные с типом процедуры должны быть виртуальными
От: mister-AK Россия  
Дата: 10.11.04 16:28
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

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


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


СГ>А вот, интересно, с точки зрения предметной области такие термины как class, private, protected, property get/set, случайно не являются искусственными понятиями?


служебное слово class — да искуственное, теримин — нет, потому что можно подразумевать и другие списковые, как запись или интерфейс или даже метод


type
  A = class (TObject)
  // здесь содержатся поля типа
  end;

  B = class (A)
  // здесь содержатся поля типа
  end;


вполне можно бы записать на придуманном языке и так:


type

object is // так можно сказать, что списковый тип декларируем, т.е. задаём
// здесь содержатся поля типа
end;

A is object
// здесь содержатся поля типа
end;

B is A
// здесь содержатся поля типа
end;

Re[5]: Связанные с типом процедуры должны быть виртуальными
От: Silver_s Ниоткуда  
Дата: 10.11.04 18:56
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>.... Куда ни ткни везде с модульностью — ни каких проблем, а с пространствами имен сплошные грабли. Вот и тут опять же такие грабли они подложили. Из-за namespace выходит нельзя делать методы обычными не связанными с типом процедурами...



А в чем проблема то непонятно все же есть например в том же C#
Я согласен что функции-члены иногда нарушают инкапсуляцию. Особенно если они крупные и сложные.
Ну дык для этго эти функции нужно вынести в другой класс, и сделать их статическими, да еще и конструктор этого класса закрыть и получится
ИМХО, совершенно нормальное яление если есть класс только с одной функцией (статической), если у этой функции больше 100 строк да еще и если ее удобно разбить на вспомогательные функции, тогда конечно нужно выносить, еще и закрыть можно вспомогательные функции.

Классы в C# это те же модули о которых ты говоришь, тоько возможностей побольше.
Re[3]: Связанные с типом процедуры должны быть виртуальными
От: Шахтер Интернет  
Дата: 10.11.04 20:30
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Здравствуйте, 0xDEADBEEF, Вы писали:


DEA>>- В boost наблюдается похожая тенденция: функции-экстракторы из различных контейнеров (boost::any,boost::variant,boost:shared_ptr) реализованы как не-члены.


DEA>>Чем мотивируется решения в Бусте — не знаю, но подозреваю что они прислушались к Александреску.

ЗХ>Тем, что по-другому невозможно. У функции-члена нельзя явно прописывать инстанциацию (тьфу, о чем я? короче, в терминах запутался, вот пример: )
ЗХ>
ЗХ>any.get<int>(); //так низзя
ЗХ>get<int>(any); //а так - мона.
ЗХ>

ЗХ>Если только я ничего не путаю

Путаешь -- можно, использую в некоторых случаях ключевое слово template.

any. template get <int>();
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[11]: Связанные с типом процедуры должны быть виртуальными
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 11.11.04 05:42
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

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


СГ>Вот членораздельный аргумент:


СГ>Если есть 500 файлов исходников, значит есть 500 динамически загружаемых модулей...


И плюём на производительность — не наша это проблема, нехай юзверя покупают 2-ух процессорные системы на основе четвёртых пней, дабы загружать и динамически линковать всё это добро...

СГ>Внес изменение в 1 текстовый файл, скомпилировал его в 1 маленький исполнимый файл, заменил старый исполнимый файл на этот новый во всех уже проданных по всему миру системах и спишь спокойно. А можно заменить его не на один, а, например, на три новых модуля.


Далее прогоняешь тучу тестов для всех возможных комбинаций версий 500 модулей, натравливаешь на это дело 5 отделов тестировщиков, которые месяц гоняют эту систему. Таки выпускаешь этот килобайтный модуль в свет и молишься, чтобы у клиентов всё срослось. А через день почтовый сервак падает под напором жалоб о неполадках от клиентов и служба поддержки в полном составе кончает жизнь ритуальным сеппуко, потому как не протестили совместимость с 5-ю древними модулями, которые клиенты не потрудились в своё время обновить, а вы их потеряли за давностью лет.

СГ>Вдобавок, некоторые системы могут использовать разные модули от различных производителей.


Угу, были такие эксперименты — нафиг нафиг. Сторонний производитель меняет что-нибудь в своём модуле, клиент ставит обновлённую версию и на следующий день заявляет вам — ваше приложение падает когда я кликаю мышкой и ищи потом почему оно падает (клиенты очень редко удосуживаются сообщать даже код ошибкм, не то что информацию об установленых модулях). В случае MS Windows это называется DLL Hell...

СГ>Еще вдобавок: Понадобилось добавить в систему новую функциональность — это элементарно, создаешь несколько дополнительных модулей расширяющих данную систему и рассылаешь их всем заинтересованным в расширении своей системы потребителям. Причем разных расширений модульной системы может быть очень и очень много. Третьи фирмы могут штамповать эти расширения на ура!


Только не забудьте наладить производтсво хрустальных шаров, чтобы ваша система могла с их помощью узнавать о новой незапланированной в ней функциональности...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[6]: Связанные с типом процедуры должны быть виртуальными
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 11.11.04 05:47
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, Кодт, Вы писали:


К>>В С++ приходится заявлять — этот и этот мне друзья, со всей ответственностью. Просто не дружите с кем попало, и будет вам щастье.

S> Интересно, а почену в Net отказались от столь эффективных друзей в пользу ассембли и комбинации её с protected ????
Не знаю, почему они отказались от друзей, но имел я в гробу эту комбинацию ассемблей с protected... Это так чистое ИМХО и крик души, прошу на данное сообщение не отвечать — флеймить не буду...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[12]: Миф
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 11.11.04 06:52
Оценка: -4 :)
Здравствуйте, Mr. None, Вы писали:

MN> И плюём на производительность...

MN> Далее прогоняешь тучу тестов...
MN> Сторонний производитель меняет что-нибудь в своём модуле...
MN> Только не забудьте наладить производтсво хрустальных шаров...

Это всё мифы появившиеся в результате использования опасных языков программирования Си/Си++ и им подобным. Для таких языков даже невозможно написать компилятор, который мог бы предотвратить buffer overflow. Вот, совсем недавно, Владимир Лось, переписывая аудиокодек с C на Active Oberon в очередной раз столкунулся с порочностью языка Си:

С точки зрения Оберона, то, что творили операторы со структурами данных в сишной программе было маразмом и извратом. И если бы это только вело к эффективности!!! Переписанная мной процедура обратного Фурье-преобразования на порядок эффективнее оказалась сишного исходника.
....то, что было наворочено в сишнике, обероновский компилятор бы просто как ахинею не пропустил бы. И ещё раз на поверку оказалось, что таки да, там туфта была... Например по их алгоритму индекс ИНОГДА (“ну не всегда же!” :о) ) выходил за верхний предел. Знаете, как оне из этого трабла вышли? ГОСПОДА ДОБАВИЛИ ТРИ ДОПОЛНИТЕЛЬНЫХ ЭЛЕМЕНТА В МАССИВЕ С НУЛЕВЫМИ ЗНАЧЕНИЯМИ!!! Как вам такое “проектное решение”? Видимо у них рантайм-ероры начали сыпаться и они, вместо того, что бы пересмотреть алгоритм формирования индекса, просто добавили столько элементов (“какой максимальный индекс “получается по статистике”?” :о) ). А и правда – а нафига? — слушатель всё равно раз в пять секунд вкрапление “лишнего нулевого значения” в амплитуде сигнала не заметит при 48 тысячах выборок в секунду... :о)))

http://www.delphikingdom.com/asp/talktopic.asp?ID=285&amp;Order=0&amp;Count=10&amp;pNo=3

Использование безопасных (safety) языков программирования таких как языки Oberon family позволяет создавать надежные расширяемые модульные операционные системы (не пользующиеся виртуальными адресными пространствами, а работающие всего лишь с одним единственным адресным пространством, в результате чего производительность таких систем превосходит производительность Linux в десятки раз). Кстати, на счет юникса — там разработчики даже на виртуальные адресные пространства не шибко надеются, оказывается там делают специальные "щели" в адресном пространстве между ядром и программами — это на тот случай если вдруг случайно будет небольшой buffer overflow, то чтоб он данные у других программ не попортил.

Модульная расширяемая система от того и называется расширяемой, что добавление в нее нового модуля не может привести к поломке в уже установленных модулях. Добавление нового модуля не обязывает проводить полный integrity check. Если каждое добавление нового модуля обязывало бы проводить полную проверку целостности, то такая система не могла бы называться РАСШИРЯЕМОЙ просто по определению расширяемых систем.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.