Как получить статическую функцию вызывающего подкласса 'name in the superclass'? - PullRequest
2 голосов
/ 24 октября 2019

Предположим, у нас есть Check.m:

classdef Check < handle
methods (Static)
    function doStuff()
        if isCalledFromAssertSubclass
            % do this stuff only if called as Assert.doStuff(), not if called as Check.doStuff()
        end
        % do other stuff
    end
end
end

и Assert.m:

classdef Assert < Check
    % nop
end

Как написано в комментарии, я бы хотел, чтобы Check.doStuff() выполнялся толькострока "do other stuff" и Assert.doStuff() также выполняет блок if isCalledFromAssertSubclass.

Я хочу использовать статические методы, чтобы не создавать новый объект Assert всякий раз, когда мне нужноутверждают. Использование глобального объекта assert также очень уродливо и требует строки global assert в каждой функции, которую я хочу использовать assert. Аналогично для проверок.

Итак, есть две проблемы:

  1. Поскольку это статические классы, нет никакой возможности использовать class(obj) или любое другое свойство или функцию нестатического класса.
  2. dbstack не поддерживает наследование и всегда возвращает Check в качестве вызывающего класса, также для Assert.doStuff.

Я нашел рабочее решение, которое использует комбинациюdbstack и dbtype для чтения строки, из которой поступил вызов, т.е. строки, в которой написано Assert.doStuff(). Однако он включает в себя две функции отладки, которые, вероятно, не должны использоваться в производительном коде, и более важен, dbtype очень медленный (в моем случае 30 наших из 70 секунд!).

Я мог бы вместо этого использовать пакет (каталог+Check с файлами функций там) и создайте символическую ссылку +Assert -> +Check. Тогда я мог бы проверить имя файла, но это а) не переносимо, б) довольно некрасиво и в) также несколько медлительно (я полагаю).

Есть ли более быстрый способ для этого?

1 Ответ

2 голосов
/ 24 октября 2019

Почему бы не перегрузить статический метод для Assert и заставить его вызывать метод родителя, когда это будет сделано? Это нормальный способ использования наследования: вы не хотите, чтобы родитель, Check, знал что-либо о своем потомке, Assert.

Вот как это будет выглядеть:

classdef Assert < Check
methods (Static)
    function doStuff()
        % do some stuff
        Check.doStuff()
    end
end
end

Как @ Вольф предлагает в комментарии , вышеприведенное работает, пока Check.doStuff не запечатан. Запечатанный метод не может быть перегружен. См. документацию .

...