2
votes

My initial foray into loadobj: I found the a code pattern and explanation:

If the load function encounters an error, load passes loadobj a struct instead of an object

My load errors come from setters that use properties that haven't yet been assigned to in the load process. I want to define a loadobj method that avoids said errors and avoids copying from a struct altogether. I do that by setting the properties in the order that they are meant to be set. Using the code pattern from the above webpage:

methods(Static)

   function oOut = loadobj(oIn)

      if isstruct( oIn ) % Diagnostic breakpoint set here
         error('Load failed');
      end % if

      % Example code pattern shows input object assigned to output
      % object, but I want to control the order in which
      % properties are assigned to

      oOut.TstepPrYr = oIn.TstepPrYr;
      oOut.TwinYrs = oIn.TwinYrs;
      oOut.Twin1sidePadYrs = oIn.Twin1sidePadYrs;

      % The following properties should have been set by setters
      %     TwinPaddedYrs
      %     TwinPaddedDays
      %     TstepDays
      %     TwinPaddedTsteps % Not used

      % There are also many other properties.  With the key
      % properties set, I should now be able to copy the rest in
      % one shot.

      oOut = oIn;

   end % function

end % methods(Static)

Right at the top, I trap the case where the input argument is a struct. Such a condition would mean that load failed with when input argument was a bonafide object. I shouldn't continue in that case -- I should fix the loadobj code instead.

Since loadobj assigns values to properties in the right order, it should never fail, and hence, it should never be called again with a struct argument. Unfortunately, I'm still erroring out in a setter due to non-existent property values. I put in a breakpoint at the top of loadobj to see if the input argument is indeed a struct -- it is! So loadobj probably isn't even being called with a bonafide object. I conjecture that Matlab's default loading code (and load ordering) is being used instead. According to the top of the loadobj help, this is not what I should expect.

Can someone please suggest what I can do to further troubleshoot this? In case it matters, my class is derived from matlab.mixin.Copyable.

Odd behaviour observed: If I use the debugger to continue right into the above error statement, it generates a Matlab warning instead of an error. But it still exits.

1
Did you implement saveobj? load builds your object, then calls loadobj. If building the object fails, it calls loadobj with a struct. In your case, building the object initially fails. Define a saveobj that outputs a struct with those three fields. - Cris Luengo
I haven't implemented a saveobj, but from what I read, it shouldn't be necessary in order to use loadobj. In the interest of avoiding extraneous code, I am just trying to implement loadobj, which (apparently) can be done, and isn't necessarily even discouraged. I thought that the issue here is just understanding how loadobj works. Does it get called with an object first, and re-called if that fails? The fact that the example pattern contains if isstruct... seems to imply exactly that, and the loadobj help also seems to imply that. - user36800
Yes, it looks like it does exactly that. But if it calls your function with an object of your class, it has already constructed it. Why do you need to re-construct it then? What is the point of this loadobj? Given that your objects cannot build without the loadobj, you'll have to make it so that a struct is passed to loadobj. And you do that by defining a saveobj. - Cris Luengo

1 Answers

0
votes

I believe you need to move the line oOut = oIn; to before you start initializing properties. The variable oOut isn't initialized to an object by default; it is initialized to a structure when you start assigning properties with dot notation. Alternatively, you could initialize oOut with a call to the constructor, then move properties from oIn.

Having the line oOut = oIn; at the end of the loadobj method simply sets oOut to the unaltered oIn object that was passed, without any modifications.