Size: a a a

2021 May 02

g

gui in dlang.ru
--link-defaultlib-shared
источник

KF

Konstantin Firsov in dlang.ru
Архитектурный вопрос. Наверху иерархии конфига есть базовый класс, он описывает контракты. В нем должны быть абстрактные методы, допустим getValue и setValue. Если сделать первый как T getValue(T)(string key), то компилятор это разрешает и оно работает, но потомок не может указать override, шаблоны не виртуальные, а без явного переопределения это выглядит неправильным. Поэтому убираю getValue из рутового конфига, там все равно есть специализированные методы для разных значений и он не критичен, проблема отпадает.

Во втором же void setValue(T)(string key, T value) при попадании T в аргумент компилятор сразу начинает рассматривать его как частный случай шаблона в интерфейсе\абстрактном классе - финальный метод, который не может быть абстрактным и должен иметь реализацию, если её представить, то будет вызываться только он, когда как его переопределять должны потомки.

Параметризовать сам класс конфига нельзя, т.к. он рутовый, везде в его использовании будет нужна параметризация. Можно попытаться убрать абстрактность, сделать класс обычным, но, шаблоны все равно не виртуальные и не переопределяются, template mixin тоже выглядит бесполезным. Если обернуть значение в какой-нибудь ConfigValue, то все равно нужно указывать параметризацию. Самый грубый вариант - затереть тип строкой setValue(string, string), но это лишняя конвертация и сильно осложняет валидацию попадающих туда значений и корректную запись в конфиг, хотя если методы будут протект, то тогда потомок может сделать ту же валидацию, но все равно попахивает дичью.

Наиболее логичным выглядит std.variant т.е. setValue(string key, Variant value), но из него get также требует указания типа, получается что для разных типов нужны проверки либо на прямое Variant.type == typeid(foo), либо Variant.convertsTo!(foo), что скорее всего закончится неочевидными граблями или шансом получить в конфиге не то, что хотелось бы, ну и более сложные типы вроде массива\мапы имеют разные типы. Да и при установке значения конфига каждый лишний раз нужно делать присваивание в переменную с Variant, что немного утомляет.

Есть ли еще какие-нибудь более удачные варианты или я не вижу чего-то очевидного?
источник

МВ

Макс Воробьев... in dlang.ru
конфиг в каком формате?
источник

DH

Dark Hole in dlang.ru
overrride + шаблоны — это нерабочая комбинация. К тому же мне совершенно непонятно, зачем наследовать конфиг???
источник

Тᅠ

Туночка ᅠᅠ... in dlang.ru
всмисле
источник

DH

Dark Hole in dlang.ru
Что тебе непонятно?
источник

Тᅠ

Туночка ᅠᅠ... in dlang.ru
низщя преершгрузить шаблонний метод чи шо?
источник

МВ

Макс Воробьев... in dlang.ru
да
источник

МВ

Макс Воробьев... in dlang.ru
шаблонный метод - это только шаблон. как ты его перегрузишь?
источник

Тᅠ

Туночка ᅠᅠ... in dlang.ru
а ну ладно
источник

DH

Dark Hole in dlang.ru
(есть варики но это надо чорно магически ебашить в компилятор)
источник

МВ

Макс Воробьев... in dlang.ru
возможно там есть какой-нибудь readConfig(Config) который читает абстрактный конфиг и т д
источник

DH

Dark Hole in dlang.ru
По заветам Дениса: #ненужно
источник

МВ

Макс Воробьев... in dlang.ru
возможно стоит уйти от override и сделать на шаблонах
источник

KF

Konstantin Firsov in dlang.ru
Ну, как мне нужно: по приложению должно быть разбросано апи только рутового класса конфига, чтобы менять конфиги один на другой. Например, я уже менял proper-d, который неаккуратно взял вначале на yaml. Значит где-то должны быть методы, общие для всех конфигов, чтобы приложение ничего не знало о конкретной реализации и что там под капотом. В принципе, проблема остается лишь в методе setValue, который вызывается в приложении и должен быть максимально гибким. Есть, конечно, вариант тоже закрыть этот метод и показывать только специализированные как общие setLong, setDouble и т.п., + это позволит сделать их валидацию, как setPositiveLong, setFiniteDouble и что-то такое, но, блин, это крайне затратно и большей частью не нужно.
источник

KF

Konstantin Firsov in dlang.ru
вот для получения значения - нужно, чтобы из конфига не прилетела пустая строка или прочая дичь, а при установке, как правило, там сразу с правильным типом все идет.
источник

DH

Dark Hole in dlang.ru
Зачем getValue/setValue если есть дактайпинг + шаблоны?
источник

DH

Dark Hole in dlang.ru
Ладно я понимаю, что ты не хочешь прибивать к одному единственному типу конфигов всё приложение (хотя лично мне не особо понятно зачем)
источник

DH

Dark Hole in dlang.ru
Но шаблоны тут тогда почему не подходят?
источник

KF

Konstantin Firsov in dlang.ru
В d либы порой бывают не особенно стабильны и я бы не мудохался, если бы конфиг не был сквозной зависимостью, который разбросан по всему приложению, что-то рефакторить потом в случае изменений себе дороже, проще сразу пострадать и подстраховаться, мне кажется.
а есть где-нибудь пример конфига на шаблонах? в базовом классе в любом случае параметризации быть не должно, да и чем его параметризовать, когда при установке туда могут попадать самые разные значения или как тут они используются?
источник