Matlab: средство получения запускается перед конструктором?

#matlab

#matlab

Вопрос:

Учитывая объект с пользовательскими get-методами для некоторых свойств, выполняет ли Matlab часть кода (средство получения) перед выполнением конструктора класса?

Даже если я установлю для свойства по умолчанию значение empty и получатель (!) откроет соединение ввода-вывода с файлом, когда я выполняю отладчик, даже в первой строке объект уже определен как file.io (с путем к файлу, который соответствует информации, доступной для объекта до запуска конструктора). Как это может быть, и каковы причины этой реализации?

Редактировать: Точка останова в методе get не останавливает отладчик, поэтому я не уверен, выполняется ли оно на самом деле или нет.

Редактировать 2: Похоже, что средство получения выполняется после ввода конструктора, после остановки отладчика в первой строке, до выполнения первой строки. Однако в методе get нет остановки в точке останова…


Согласно запросу, некоторый код:

 classdef Cat < handle
properties
    filename
    poop = [];  % my data matrix the cat is there to produce/manage
end
methods
    function obj = Cat(config)
        obj.filename = config.FILENAME; % Halt debugger in this line
    end
    function value = get.poop(obj)
        obj.poop = matfile(obj.filename)
        value = obj.poop.ingredients; % 'ingeredients' being the name of the variable in poopfile.mat
    end
end
end
  

Для отладки я вызываю

 myCat = Cat(config)
  

из другого скрипта. Рабочее пространство очищено, а путь изменен.

Когда отладчик останавливается, obj.poop не является [] , но уже является ссылкой на некоторый неопределенный файл и ссылкой на связанный файл obj.poop.Исходный код пуст, что очевидно, поскольку obj.имя файла еще не задано.

Комментарии:

1. Не могли бы вы вставить соответствующий код вашего класса, просто чтобы было более понятно, о чем вы спрашиваете, пожалуйста?

2. Определяется ли ваше Dependent свойство getters как Static ?

3. Насколько мне известно, мое свойство не является ни зависимым, ни статическим (возможно, будучи зависимым, оно где-то подразумевается?) Спасибо!

4. Спасибо за публикацию кода, я его прогоню и вернусь с отзывом.

Ответ №1:

Настройка теста:

С немного измененным классом Cat.m :

     classdef Cat < handle
            properties
                    filename
                    poop = [];
            end

            methods
                    function obj = Cat(config)
                            display('In constructor.');
                            obj.filename = config.FILENAME;
                    end

                    function value = get.poop(obj)
                            display('In poop getter.');
                            obj.poop = matfile(obj.filename);
                            value = obj.poop.ingredients;
                    end
            end
    end
  

для отображения порядка выполнения методов класса и test.m скрипта:

     ingredients = 1:100;
    save('a', 'ingredients');

    config.FILENAME = 'a.mat';

    myCat = Cat(config)
  

Я получил следующий результат:

     >>test
    In constructor.

    myCat = 

    In poop getter.
      Cat handle

      Properties:
        filename: 'a.mat'
            poop: [1x100 double]

      Methods, Events, Superclasses
  

Пожалуйста, обратите внимание, что первое назначение в методе getter заканчивалось точкой с запятой (в то время как в исходном коде этого не было).

В заключение:

  1. get.poop() Метод вызывается после конструктора, как и ожидалось. Это было протестировано на MATLAB R2012a, но я твердо убежден, что это не вопрос версии.

  2. Причина, по которой вызывается get.poop() метод, заключается в том, что присваивание myCat = Cat(config) не заканчивается точкой с запятой ; .

Обоснование:

Поведение по умолчанию для назначений, не заканчивающихся точкой с запятой, заключается в отображении результата назначения. Отображение объекта означает, среди прочего, отображение значений общедоступных свойств. Вызывается для получения значения общедоступного свойства poop , get.poop() ; это объясняет вызов средства получения. Как только оператор изменяется на myCat = Cat(config); , средство получения больше не вызывается, потому что результат присваивания больше не отображается.

Последующее примечание:

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

Комментарии:

1. Ха-ха-ха, гений, спасибо, что разобрался в этом. Это имеет смысл!

2. @phi Ну, такого рода «квантовые» средства получения (наблюдение за объектом изменит объект) всегда доставляют проблемы. Я знаю, что это безответственный совет, и я не хочу показаться покровительственным, но — если вы спросите меня — вам было бы лучше использовать «классический» getter без побочных эффектов. Это означает, что откройте файл .mat в конструкторе, а не в средстве получения.

3. Спасибо, я ценю совет 🙂 Это немного сложнее, хотя матрицы слишком велики, чтобы поместиться в ОЗУ, и мне нужно загружать / выгружать их в зависимости от других состояний моего приложения. Кроме того, другие инструменты обращаются к тому же поставщику данных и получают к ним прямой доступ. Итак, мне нужно убедиться, что данные предоставляют правильные данные при обращении к ним. Загружаются не только файлы matf, но также файлы xls и csv…

4. Для тех суперумных людей, которые думают, что знают лучше (он же я три недели назад): Доверяйте этому человеку. Он знает. Неважно, насколько умным вы себя считаете, это не так.