Управление мета-классами в MatLab

Mar 14, 2024 17:19

В MatLab есть функция isa(object, className), которая проверяет, является ли данный объект «совместимым» с указанным классом (либо объект самого класса, либо объект одного из наследующих классов). Оно само по себе плохо, иметь код с такими проверками, но так уж получилось, у нас такое есть. Например, когда в одном файле хранятся объекты разного типа (скажем, актив и пассив), а я хочу прочитать их и сделать какую-то операцию только с объектами определённого типа (скажем, только с активом, посчитать общую сумму). Я мог бы базироваться на имени переменных, но это для меня ещё хуже, чем проверять тип данных.

Так вот, функция isa. Проблема для меня в слове «name» - я не люблю использование строк в этом контексте. Например, если я поменяю название класса, я хотел бы, чтобы функция isa не просто отвечала «ой, нет», а выдавала ошибку «не знаю такого класса» (причём лучше даже ещё на этапе компиляции). Ну и всякие там утилиты рефакторинга (предположим, они когда-нибудь появятся и для MatLab) лучше бы работали, если бы это была не просто строка, а прямая отсылка к классу.

При этом за последние годы в MatLab дописали много связанного с reflexion, полез в RTFM. Вижу, что есть класс meta.class, у которого есть свойство Name - это же то, что мне надо! Осталось понять, как получить объект этого класса, соответствующий нужному мне классу. Откопал, что есть какой-то убогий синтаксис ?MyClass. Убогость его в том, что эта конструкция вырывается из общей структуры программы на MatLab - что за вопросительный знак? Почему это нельзя было хотя бы оформить в виде свойства или метода (как это сделали в java)? И таки да, за счёт этой убогости я не могу прицепить эту инструкцию к последующим вызовам. То есть не работает не только двусмысленный ?MyClass.Name, но и очевидный (?MyClass).Name. Только через временную переменную: сначала meta = ?MyClass, а уже потом meta.Name.

Пишу в support. Пускай, если не покажут как сделать, то хотя бы запишут запрос для следующей версии.

Первый ответ. Да, лучше всего использовать временную переменную. Но можно и без неё. Объект класса meta.class можно получить не только через класс, но и через объект этого класса. См. метод class(myObject). А если у вас нет под рукой объекта нужного вам класса (нет, у меня в этот момент его как раз нет), то вы можете попытаться схитрить и написать class(MyClass()) - при условии, что у вашего класса есть пустой конструктор. Нет, и пустого конструктора у меня тоже нет. Более того, у меня куча абстрактных классов, так что даже создать пустой конструктор исключительно для этого использования - это не вариант.

Второй ответ. Вы знаете, мы тут посоветовались с разработчиками, и к вашей проблеме можно подойти с другой стороны. Вы уже знаете, как получить meta.class нужного вам класса: ?MyClass. И у вас есть объект, для которого вы тоже можете получить meta.class его класса: class(myObject). Осталось только сравнить эти два мета-класса, а для этого у нас есть операторы «>=» и «<=»! Стоп, думаю. Они мне что, предлагают тупо проверять на идентичность два объекта класса meta.class? А если у меня класс объекта наследует от проверяемого класса: это совместимые, но разные классы, объекты их meta.class будут разными.

Прежде чем выругаться «что вы меня, за идиота держите?!», проверяю - а оно работает. Реально, я могу арифметически сравнивать два объекта meta.class, и наследующий класс строго меньше наследуемого, а наследуемый строго больше наследующего. При этом, если сравнивать два класса из разных ветвей, то любое сравнение (больше, меньше, равно) будет выдавать негативный результат.

Пишу в ответ: хмм... спасибо, это, конечно, работает, но выглядит каким-то безумным хаком. Это хотя бы где-то документировано? Или просто «так получилось»? Основывать свой функционал на таких соплях, которые, возможно, уже в следующей версии перестанут работать, лично мне страшно. Приходит ответ: ну что вы, конечно это фича!

Тикет закрыли. Но учитывая, что изначально я стремился к большей лёгкости управления кодом (представил себе, как я буду объяснять эту строчку коллегам...), применять новые знания я не стал :-)

matlab, rabota

Previous post Next post
Up