unit + .dll


#1

В данный момент если подключить модуль к библиотеке (library) - в готовой .dll будет пространство имён с именем этого модуля.

Я давно хотел предложить, но никак не доходили руки:
Как насчёт давать всем классам в пространстве имён модуля - уровень доступа internal, что скроет это пространство имён?

  1. То как реализовано сейчас - нарушает инкапсуляцию.
    Если подключил Graph3D к своей библиотеке - ужасно неудобно если этот модуль будет видно из программы, в которой будет $reference.
    Единственный способ этого избежать сейчас - засунуть всё содержимое модуля в implementation часть библиотеки, что является костылём вселенского маштаба;

  2. Если же надо чтоб программа к которой подключается видела пространство имён - всё достаточно просто.
    Можно заменить unit на namespace в описании модуля.
    А если модуль стандартный - можно в пространстве имён (тот же namespace) описать синонимы всего что надо сделать публичным из модуля;

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

  4. Изменить это должно быть достаточно легко.
    Достаточно поменять только уровень доступа классов.
    И проверять какой тип файла сейчас компилируется - лишнее, потому что даже если в .exe сделать у всего доступ private, он будет работать так же исправно. Уровень доступа важен только при $reference.

Кто ещё знает плюсы или минусы такого изменения?


Ошибка с Dll в PascalABC.net
#2

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

Раздел implementation вам кажется плохим с точки зрения языка C#, но в Паскале это - общее место.

Библиотеки применимы, но только как альтернатива модулям. Либо пишем всё на модулях, и тогда код прилинковывается к основной программе, либо пишем всё на библиотеках и получаем кучу мелких dll.

Для странной задачи, где и в библиотеке и в модуле надо использовать Graph3D, необходимо писать прослойку для Graph3D, которая позволила бы её использовать для подключения к библиотеке.

На мой взгляд, модули категорически не предназначены для одновременного использования в библиотеках и основной программе. Дело в том, что содержимое используемых функций модуля будет прилинковываться в этом случае и к библиотеке и к основной программе, что рушит весь смысл использования библиотек и приводит к неоднозначностям.

Единственное, где можно допустить какое-то дублирование - это использование универсальных функций модуля PABCSystem.


#3

Ну и что? Если надо чтоб были совместимыми - понятное дело, классы надо засовывать в библиотеку, в namespace, и использовать классы из этого пространства имён и внутри библиотеки и внутри основной программы.

Я не говорю с точки зрения языка C#, я в нём сделал всего 1 программу за всю жизнь, не касающуюся issue паскаля.

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

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


Кроме всего прочего, ещё раз, если надо чтоб в .dll были пространства имён - надо использовать пространства имён а не модули.

А публичность классов модуля только мешает. Если её убрать - ничего нигде не сломается, всё равно до недавнего времени библиотеки в паскале были вообще неюзабельны из за обилия багов, об которые споткнулся @Kotov.


#4

которые, к сожалению, пока криво реализованы


#5

Поэтому как раз сейчас самое время править базовые вещи, а не когда все привыкнуть использовать модули вместо пространств имён.


#6

Ну серьёзно

Этот код должен работать

А кроме них что-то можно нормально использовать? Пока что модули это наиболее стабильное разбиение программы на несколько файлов. Но я с нетерпением жду пространства имён)


#7

Да ничего он не должен. namespацы это чистые пространства имен, которые могут компилироваться, только если подключать из программы или библиотеки.


#8

В любом случае пока это всё неюзабельно из-за:

А когда примерно ждать? Второй год уже висят эти issue


#9

Сообщение об ошибке конечно ужасное

Кстати, вот тут у меня основная претензия к сегодняшним namespaceам. Они не являются единицей компиляции и не входят в некоторую законченную единицу компиляции. По-существу, они являются сейчас аналогом include-файлов, которые сильно устарели в сегодняшнем мире и провоцируют ошибки.

Я кстати не знаю, надо ли пространство имен сохранять в одноименном файле (если Да, то пространства имен не расширишь - например, System), что будет, если модуль имеет то же имя, и что будет, если в несколько модулей проекта добавить одно и то же пространство имен. Подозреваю, что тут будет много неочевидных глюков.


#10

Нет, идея менять уровень доступа всех классов на private - вредная и неправильная.

Инкапсуляция не нарушается - как только вы подключаете модуль по uses, вся его интерфейсная часть становится видна. А библиотека - это всего лишь коллекция того, что вы в ней написали и что подключили. Всё будет видно если вы специально об этом не позаботитесь. То есть библиотека в отличие от модуля не даёт автоматические средства защиты доступа если вы ничего не будете предпринимать.

Правильный путь для защиты доступа - поместить реализацию в implementаtion часть библиотеки, но вы не хотите идти по правильному пути.

Типы которые использует библиотека, и типы которые использует программа - и не должны быть совместимы

Должны. Обязательно. Более того, это должен быть один тип. Иначе получите ошибку в стиле “тип My не совместим с типом My”

Пространства имён - это экспериментальная возможность. Её бы по хорошему нужно делать как в C# - так чтобы в одном файле можно было делать несколько пространств имен. Но это - много работы. Поэтому - я бы сказал, что пока в PascalABC.NET под чьим-то там давлением реализован легковесный синтаксис пространств имен в стиле “один файл-одно пространство имен”. Дело хорошее, но я пока не рискну им пользоваться.

Здесь - два наезда сразу. Во-первых, я ничего не могу поделать с тем, что Вам мешает в каких-то ситуациях публичность классов, которые вы сделали публичными. Про “её убрать” - это мы все хотим что-то убрать или добавить что нам удобно. Сломается. Если класс описан как публичный, он и должен быть публичным. Не надо вносить свою сложную странную логику на этот уровень. Во-вторых, библиотеки всегда работали и работают и фразы типа “они вообще не работали” - они - странные знаете ли. Это всё равно что сказать “у вас циклы тут вообще неюзабельны”. Это всё - не очень…


#11

Нет

Вы же сами создаёте файл FoldingStrategy, а namespace в нём - VisualPascalABC. И во всех файлах аналогично. И в PascalABC.NET всё это тоже уже работает. Не работает интеллисенс и файлы в папках прямо из IDE нельзя создать.


#12

А что, namespace через папки работает?


#13

нет, просто так удобно, в одной папке – один namespace из нескольких файлов


#14

А в PascalABC.NET это пока заставить работать можно ручным изменением xml-файла (.pabcproject) проекта.


#15

Не private а internal. Не то чтоб это много меняло по функционалу, но это более правильно.

Разделение программы на модули это не только возможно подключать модуль к нескольким программам, а ещё и само разделение программы на несколько файлов. Что необходимо для нормального управления структурой проекта и возможности совместной работы над проектом.

Кроме того, файлы больше 2-3к строк убивают анализатор кода.

Это если пытаться лепить их вместе, что не к чему, особенно если те типы которые в библиотеке - сделает невидимыми.

С циклами за всё время работы у меня было, вроде, всего пара issue. А у @Kotov-а при попытке использовать библиотеки (вроде зимой) возникла целая туча issue, в итоге он решил их не трогать.


#16

Осенью. Как раз когда я и пришёл на гитхаб. Я тогда решил библиотеки не трогать из-за того, что их нужно всегда таскать вместе с .exe-шником, а не из-за issue. Но багов, там, безусловно много есть и было. Особенно во вложенных библиотеках. Но больше всего мне не понравился прикол с потерей PABCSystem при подключении любой библиотеки, сделанной на PascalABC.NET


#17

А можно конкретику? Какие Issue, связанные с dll, имеются в виду?


#18

Ну, к примеру, https://github.com/pascalabcnet/pascalabcnet/issues/1400


#19

4 сообщения перенесены в тему Болталка PascalABC.NET


#20

Значит, надо чинить Intellisence (Вы, например, могли бы этим заняться, как любитель PascalABC.NET), а не заводить новые темы.