Using Setters and Getters from a Class - matlab

I have an class called TestData that houses a private property called data, which I define as a numeric array. Its goal is to take in data from various other .m files and extract the data and place it in the specified format (numeric array. So, a random_data.m file that I am currently working with spits out a 1X13 double array called Avec. I generate and instance of the class myTestData = TestData(); however, because the member variables are private I need to have getData and setData functions. The only idea I have is to pass Avec into getData (e.g. myTestData.getData(Avec)) and then store it in a temporary array that could then be used by setData to write into data; but I feel like this is bad practice as that array would need to be public. Also, would it make sense to pass the entire array in or should I pass each element in individually. I would like to have it check the data to make sure that it is in proper format, as well.
I guess in general my concept of how the class works in MATLAB may be flawed.
Thanks for your help in advance and if there is anything else that I can provide, please let me know. Below is some code. The first snippet above the class is from the separate .m file.
%Write data to file using the TestData Object
Avec = [some 1X13 double array]
myTestData=TestData; % Generate an instance of the object
myTestData.getData(Avec);
classdef TestData
properties (Access = private)
metaData % stores meta data in Nx2 array
data % stores data in PxQ array
colLabels % labels columns
colUnits % provides units
metaPrint % used to print metaData
temp % debugging purposes only
end
methods
%****************************************************************************%
%Function: TestData
%Purpose: Constructor used to allocate data arrays
%****************************************************************************%
function this = TestData() %constructor
this.metaData = [];
this.data = [];
this.colLabels = [];
this.colUnits = [];
this.metaPrint = [];
this.temp = [];
end %TestData()
%%
%****************************************************************************%
%Function:
%Inputs:
%Purpose:
%****************************************************************************%
function this = getData(this, someArray)
????
end %getData

I think you're misunderstanding the idea of getters and setters. A get function is designed to take something from the object and return it, while a setter is designed to put something into a property of the object. You would want something like:
function data = getData(this)
data = this.data;
% Do any processing to put data into a different format for output
end
function this = setData(this, data)
% Check the data input to make sure it is the right format, etc.
this.data = data;
end
You may also want to design setData to take different types of arguments, like a file name that it can use to load the matrix itself. You could also design your constructor to accept a matrix or file name and initialize data as well.
Also, as Cris alludes to in his comment, if the reason you were making data private was to control how the user could access and modify it, it's enough to just have getters and setters. You can make data public and your property access methods will still be called when accessing the object like Avec = myTestData.data or myTestData.data = Avec.

Related

Using a Simulink SimulationInput Object as a property of a class

I want to set up an object of a class, which contians all variables for a simulink model as its properties.
To later be able to use parallel simulations, I want to have a function in the methods, which takes all the properties and feeds them to a Simulink SimulationInput Object (via the 'setVariable' method),
but the setVariable-function does not fill up the variables of the object 'in' when I run it.
The code looks somewhat like this:
classdef SimSetup
properties
mdl = 'SimulinkFile'
SimulationTime = 2
Plant
in
end
methods
function this = SimSetup()
open_system(this.mdl);
this.Plant = load('PlantData.mat','xPlant');
end
function createSimIn(this)
this.in = Simulink.SimulationInput(this.mdl);
this.in = this.in.setVariable('SimulationTime', this.SimulationTime);
end
end
Thanks in advance
The mistake was the following:
I either had to use a handle class or had to return the output of the function to the object itself (in short: function this = createSimIn(this)).

Force conversion of struct to object in MATLAB loadobj function

I am working with a custom defined class I called "PathObj_Standard". I want to make sure that when I load this class, if the property CalcDate was saved as a cell array it is converted to a standard array. However, I changed the class definition some time ago, so when I use the loadobj function, I am getting a struct instead of an object. The original code I'm using has a lot more properties, so I'd rather not create a new object by assigning property by property from the struct to a new object. Furthermore, I'm also hesitant to change the constructor to accept a struct as an argument.
I tried using the class function inside loadobj, but I am getting a Cannot redefine class 'PathObj_Standard' without a call to 'clear classes' error. Isn't this function supposed to force conversion of a struct to an object? Why doesn't it work within the loadobj function?
classdef PathObj_Standard < handle
properties (SetAccess = protected)
CalcDate;
Name;
end
methods(Static)
function obj=loadobj(s)
if isstruct(s)
obj=class(s,'PathObj_Standard');
else
obj=s;
end
if not(isempty(obj.CalcDate)) && iscell(obj.CalcDate)
obj.CalcDate=cell2mat(obj.CalcDate);
end
end
end
methods
function obj=PathObj_Standard(Name,CalcDate)
obj.Name=Name;
obj.CalcDate=CalcDate;
end
end
The issue is that calling class attempts to create a class which you can't do from within your loadobj. You'll want to call the actual constructor
Also in my experience, the easiest way to construct a class from a struct is to inherit from hgsetget rather than handle as that automatically has the set and get methods of MATLAB's graphics objects and these methods can accept property/values in the form of a struct. In newer versions of MATLAB, you can also use the SetGet mixin
classdef PathObj_Standard < hgsetget
If you do this, you could change your loadobj method to be something like
function obj = loadobj(s)
% Update the input struct as needed
if isfield(s, 'CalcDate') && ~isempty(s.CalcDate) && iscell(s.CalcDate)
s.CalcDate = cell2mat(s.CalcDate);
end
% Call the default constructor
obj = PathObj_Standard();
% Update all properties that were supplied to loadobj
set(obj, s)
end

Save a Matlab Property to a mat file

I have a class with a struct property called myStruct:
properties
myStruct;
end
I would like to save the struct to a .mat file. I tried:
save -append registers.mat myStruct;
But it gives the error:
Variable 'myStruct' not found.
I have different functions for updating the struct, like:
function configureChannel( obj, Channel )
myStruct.Channel = Channel;
save -append registers.mat myStruct;
end
function updateConfiguration( obj, dataPath )
myStruct.EN = 1;
save -append registers.mat myStruct;
end
These are all functions of the same class.
I think that the main problem in this code is how you access myStruct from your functions. Take a look at the following piece of code:
function configureChannel( obj, Channel )
myStruct.Channel = Channel;
...
end
What you intended for it to do was to assign Channel into the Channel field of the current object's myStruct's Channel property. What it actually does is equivalent to calling:
myStruct = struct('Channel', Channel);
That is, you create a new local variable in the current workspace/scope of configureChannel, without actually updating the property of the object, obj.
So the first correction you need to make is how you access myStruct in your setter:
obj.myStruct.Channel = Channel;
Next is the issue of saving.
When dumping a copy of an object's field to a file, I would expect save to treat your arbitrary object as a struct, and so struct saving conventions should apply:
'-struct',structName | Store the fields of the scalar structure specified by structName as individual variables in the file. For example, save('filename.mat','-struct','S') saves the scalar structure, S.
Thus, I would expect the following to work disclaimer: I didn't test it:
save('filename.mat','-struct','obj.myStruct');
Other alternatives in case the above fails:
save('filename.mat','obj.myStruct'); % Alternative #1
tmp = obj.myStruct; save('filename.mat','tmp'); % Alternative #2
One last thing - as you may have noticed, I'm using the function form of save, because I consider it to be more maintainable/readable/fool-proof:
save(filename,variables,'-append');

hide object information in matlab

I implemented a class in Matlab which derives from matlab.mixin.Copyable. I want to suppress the output of the command window so that the user does not has information about the class. I want to do this for security reasons. For example:
a = myStack;
a
ans=
myStack with no properties.
But the user can click myStack and it gives information about the class. I know that I can overload display for this, but the behavior that I want is like follows:
b = handle(1);
b
ans=
handle
How I can do this?
Thanks.
You have to derive from matlab.mixin.CustomDisplay interface and override the getPropertyGroups method.
For the specific purpose of removing the link to help in the header, also override getHeader method.
NB: I don't see how you can truly handle security in this way. Users will still have other means to get details about your class. For instance meta = ?MyClass, or just edit MyClass if not encrypted with pcode, or simply in the editor just typing myInstance. and let intellisense list all non hidden/private methods and properties.
Example for the display you want to have:
classdef foo < matlab.mixin.CustomDisplay
properties
Login = 'root';
Password = '1234'
end
methods (Access = protected)
function [str] = getHeader(obj)
str = mfilename;
end
function [pg] = getPropertyGroups(obj)
pg = [];
end
function [str] = getFooter(obj)
str = sprintf('\n');
end
end
end
May be better solution to avoid displaying some properties (including from help-link):
classdef foo < matlab.mixin.CustomDisplay
properties (SetAccess = private, GetAccess = private) % here remove any public access, use '(Hidden)' if only want to remove from display and help
Login = 'root';
Password = '1234'
end
end
NB: Careful, as #Daniel wrote, whatever you will do, struct(a) reveals all property names and values.
As well as the method from #CitizenInsane, you may get what you want by simply adding the Hidden = true attribute to some or all of your properties.
Reiterating what others have said, though, if you're doing this in order to seriously prevent people from understanding the internals of your class, struct(a) will always show them the properties. You can overload your class with a struct method that errors out, but then builtin('struct', a) would still do the original thing. Also ?Classname will provide meta-information about the class that includes its properties.

create array of objects of a class in another class MATLAB

I am trying to create an array of objects of a class Cell in another class Systemin MATLAB. The classCell` is:
classdef Cell
properties
ID;
EntityID;
ZoneID;
NeighborID;
State;
nextChangeTime;
end
methods
% Define the constructor
function obj = Cell()
obj.ID = zeros(1);
obj.EntityID = zeros(1);
obj.ZoneID = zeros(1);
obj.NeighborID = zeros(1);
obj.State = zeros(1);
obj.nextChangeTime = zeros(1);
end
end
Now I have another class System. I try to make an array of Cell objects like this:
classdef System
properties
Cells;
end
methods
function obj = System(dimx,dimy)
obj.Cells(dimx,dimy) = Cell();
end
end
But I think I am using the wrong format. Not sure if this is possible. Any suggestions on how to accomplish this would be appreciated.
In order to be able to create arrays of objects of user-defined class (e.g. Cell class), it is convenient to have the default constructor for the user-defined class. The default constructor is the one that takes no arguments (i.e. when nargin==0). When creating arrays, the implicit initialization of the array's objects is done by this constructor. If this constructor is missing, trying to build arrays by "extending" a scalar object will generate an error.
Another way of creating arrays of objects (without defining a default constructor) is by using horzcat, vertcat and cat.
Aaaaand... when accessing the properties of an object, don't forget to mention the object you're accessing:
obj.Cells = Cell.empty(0,0); % Force the type of empty Cells to Cell class
obj.Cells(dimx,dimy) = Cell();