Может ли конструктор получить доступ к имени переменной, для которой хранится объект? - PullRequest
0 голосов
/ 16 сентября 2011

Я хочу, чтобы следующий код установил поле 'name' экземпляра myClass равным 'super_awesome_name':

super_awesome_name = myClass();

где конструктор myClass выглядит следующим образом:

function obj = myClass()
    obj.name = ???;
end

Есть ли способ сделать это в Matlab? Прямо сейчас я могу сделать что-то очень похожее с assignin, но это делает синтаксис очень неестественным:

 myClass(super_awesome_name);

где конструктор myClass выглядит следующим образом:

function obj = myClass(var_name)
    obj.name = assignin('caller',var_name, obj);
end

1 Ответ

2 голосов
/ 16 сентября 2011

Насколько я знаю, не существует удобного способа сделать это. Вы можете убедиться в этом сами, поскольку MATLAB придется выполнять некоторые действия при создании такого объекта.

  1. Сначала построить объект
  2. Сохранить этот объект в super_awesome_name

Но для шага 1 требуется информация из шага 2 (то есть имя переменной). Так что вам придется обойти это.

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

ИМХО проще создать конструктор, который принимает строку, содержащую имя (или, возможно, переменную), поскольку вы можете получить имя переменной аргумента, используя inputname). Использование inputname, однако, немного яснее, чем использование assignin.

Зачем вам такая функциональность? Я думаю о ситуации, когда вы могли бы сделать что-то вроде:

x = myObjectThatHasAName(); % x.name contains 'x'
y = myObjectThatHasAName(); % y.name contains 'y'
x = y;                      % x.name contains 'y' !

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

Если вам нужна функциональность для определения фактического имени переменной в другом методе или функции, просто используйте inputname. Тогда вам не нужно будет самостоятельно отслеживать имя переменной со всеми запутанными последствиями. Это было бы то, что я предложил бы сделать в большинстве случаев. Вы можете увидеть пример в документации MATLAB.

С другой стороны, я думаю, что самым простым способом хранения имени переменной внутри объекта может быть что-то вроде:

classdef myObjectThatHasAName
   properties
      name = '';
   end
   methods
      function obj = myObjectThatHasAName()
      end
      function obj = storeName(obj,name)
         if nargin < 2
            name = inputname(1);
         end
         if ~isempty(name) % && isempty(obj.name)
            obj.name = inputname(1);
         end
      end
   end
end

Я не проверял это (отсутствие MATLAB на моем текущем компьютере), но следующий код должен это сделать:

x = myObjectThatHasAName();
x = x.storeName(); 
% or x = storeName(x);
% or x = storeName(x,'x');

Если вы не возражаете против накладных расходов, вы всегда можете включить storeName в каждый другой метод (и забыть о вызове storeMethod вне методов). При этом отслеживается имя переменной, в которой находился объект до последнего назначения. Возможный метод может выглядеть следующим образом:

function obj = otherMethod(obj,arguments)
   obj = obj.storeName(inputname(1));
   % actual code for the method
end

Таким образом, имя задается при первом вызове любого метода для объекта (это почти делает то, что вы хотите, но я думаю, что в большинстве случаев это будет делать то, что вам нужно). Конечно, вы можете изменить код так, чтобы он запомнил первое назначение (просто закомментируйте код в storeName).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...