LudoZ
LudoZ

Reputation: 11

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

Upvotes: 1

Views: 345

Answers (1)

Suever
Suever

Reputation: 65430

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

Upvotes: 2

Related Questions