2016-03-09 4 views
0

Я пишу определение класса, которое использует прослушиватели для изменения объекта, когда установлены определенные свойства. Вроде так:В Matlab, какой правильный синтаксис для передачи новых переменных при использовании прослушивателя PreSet

classdef MyObject < handle 
    properties (SetObservable) 
     orientation = 'h'; % h = horizontal, v = vertical, o = other 
     length 
     width 
    end 
    methods 
     % Constructor 
     function mo = MyObject(o) 
      mo.orientation = o; 
      addlistener(mo, 'orientation', 'PreSet', @mo.changeOrientation); 
     end 

     % Change Orientation Listener 
     function changeOrientation(mo, src, evnt) 
      celldisp(src); 
      celldisp(evnt); 
      % I want a way to access newor here 
      if mo.orientation == 'h' && newor == 'o' 
       tempw = mo.width 
       mo.width = mo.length 
       mo.length = tempw; 
      end 
     end 

     % Setter 
     function set.orientation(mo, newor) 
      mo.orientation = newor; 
     end 
    end 
end 

Я хочу иметь возможность использовать переменный новичок, когда устанавливаю ориентацию. Как передать новую переменную ориентации в метод changeOrientation?

Я хочу, чтобы избежать перемещения содержимого changeOrientation в метод set.orientation, потому что Matlab жалуется на свойства (длина и ширина), которые потенциально не инициализируются.

EDIT длина НЕ зависит от ориентации. Мне просто нужно поменять длину и ширину при изменении ориентации. В других случаях пользователь должен иметь возможность устанавливать длину или ширину в любое положительное значение.

ответ

1

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

Целью использования прослушивателя PreSet является получение значения свойства до, оно изменено, но не должно изменять значения до их фактического назначения.

В коде, который вы опубликовали, я, скорее всего, сделаю любую проверку/изменение ориентации в методе set.orientation вашего класса.

function updateLength(mo) 
    % Change mo.length here and others based on mo.orientation 
end 

function set.orientation(mo, newor) 
    % validate newor 
    if dovalidation(newor) 
     mo.orientation = newor; 
    else 
     error('invalid!'); 
    end 

    % Now trigger a "callback" 
    mo.updateDependentVariables() 
end 

EDIT

Основываясь на ваш комментарий, вероятно, лучший способ пойти об этом, чтобы сделать length иметь теневую свойство length_, который содержит значение, которое пользователь присваивает length. Когда пользователь запрашивает значение length он может либо вернуть это сохраненное значение (если ориентацию == «v») или width (если ориентация == «Н»)

classdef MyObject 
    properties (Dependent) 
     length % Can be either `width_` or `length_` 
     width % Can be either `width_` or `length_` 
    end 

    properties 
     orientation 
    end 

    properties (Access = 'protected') 
     length_ = 12 
     width_ = 10 
    end 

    methods 
     function mo = MyObject(o) 
      mo.orientation = o; 
     end 

     function set.orientation(mo, newor) 
      % If the user supplies an "o" flip the orientation 
      if strcmpi(newor, 'o') 
       if strcmpi(mo.orientation, 'v') 
        newor = 'h'; 
       else 
        newor = 'v'; 
       end 
      end 

      mo.orientation = newor; 
     end  

     function set.length(mo, value) 
      if strcmpi(mo.orientation, 'h') 
       self.length_ = value; 
      else 
       self.width_ = value; 
      end 
     end 

     function set.width(mo, value) 
      if strcmpi(mo.orientation, 'h') 
       self.width_ = value; 
      else 
       self.length_ = value; 
      end 
     end 

     function res = get.width(mo) 
      switch lower(mo.orientation) 
       case 'h' 
        res = mo.width_; 
       case 'v' 
        res = mo.length_; 
       otherwise 
        error('Invalid orientation'); 
      end 
     end 

     function res = get.length(mo) 
      switch lower(mo.orientation) 
       case 'h' 
        res = mo.length_; 
       case 'v' 
        res = mo.width_; 
       otherwise 
        error('Invalid orientation'); 
      end 
     end  
    end 
end 

Таким образом, вы не имеете для явного обновления length при изменении ориентации.

Как примечание стороны, я бы не использовать length как свойство, как получает немного запутался с встроенной функцией length.

+0

Это то, что я хотел бы сделать. Однако у меня есть другое свойство, длина, которое изменится при изменении ориентации. И когда я пытаюсь установить 'mo.length' в методе' set.orientation', Matlab сердится на меня и говорит, чтобы я этого не делал. – toshiomagic

+0

@toshiomagic Да MATLAB жалуется на это. Это связано с тем, что во время построения объекта или загрузки из файла не гарантируется, что значения 'length' и' orientation' являются допустимыми.Считаете ли вы, что 'length' является динамическим свойством? Можете ли вы обновить свой пост, чтобы включить информацию об этом другом свойстве? – Suever

+0

@toshiomagic Вы также можете настроить функции «обратного вызова», как я уже отмечал выше, что аналогично предыдущей настройке без прослушивателя. – Suever

0

Для этого вам не нужен дополнительный прослушиватель. Вот для чего нужны собственные методы setter/getter. Нет смысла использовать метод set.orientation, как в вашем примере, он ничего не делает, кроме назначения, которое все равно произойдет. Вместо этого используйте этот метод, чтобы сделать дополнительный звонок changeOrientation:

classdef MyObject < handle 
    properties (SetObservable) 
     orientation = 'h'; % h = horizontal, v = vertical 
    end 
    methods 
     % Constructor 
     function mo = MyObject(o) 
      mo.orientation = o; 
     end 

     % Change Orientation Listener 
     function changeOrientation(mo, newor) 
      % Use newor here! 
     end 

     % Setter 
     function set.orientation(mo, newor) 
      mo.changeOrientation(newor); 
      mo.orientation = newor; 
     end 
    end 
end 
+0

Могу ли я установить другие переменные внутри changeOrientation? См. Комментарий к другому ответу. – toshiomagic

+0

Да, вы можете - вам нужно сделать одно из свойств [Dependent] (http://uk.mathworks.com/help/matlab/matlab_oop/access-methods-for-dependent-properties.html) с другой. –

+0

Пользователь может изменить длину в любое время. Он не зависит от ориентации. Мне просто нужно поменять ширину и длину при изменении ориентации на «o». – toshiomagic

Смежные вопросы