loadobj() always called from matfile() regardless of subsref

MATLAB calls loadobj() whenever you access the contents of a saved matfile, if there's an object saved there. Example:
classdef toomanyloadobj
methods
function obj = toomanyloadobj()
disp('->constructor');
end
end
methods (Static)
function obj = loadobj(s)
obj = toomanyloadobj(); % must return obj with this class
disp('->loadobj');
end
end
end
Script to run:
clc;
x = 1;
disp('new instance');
obj = toomanyloadobj();
disp('save mat');
save('toomanyloadobj.mat','obj','x');
disp('matfile');
mat = matfile('toomanyloadobj.mat');
disp('look at x (but it also looks at everything else)');
mat.x
disp('load only x');
s = load('toomanyloadobj.mat','x');
Output:
new instance
->constructor
save mat
matfile
->constructor
->loadobj
look at x (but it also looks at everything else)
->constructor
->loadobj
ans =
1
load only x
So even if I just want the value of "x" from the matfile, it reruns loadobj() every time I access mat. This is a huge problem if I have several objects saved and each has its own (possibly complicated and time-consuming) loadobj().
As you can see, if I directly load "x" using load(..,'x'), it works fine, but there are advantages to using matfile() which I'd rather retain, like the ability to load variables and write to the mat file directly.
Any workaround?

6 Comments

This syntax will also trigger loadobj,
x = load('toomanyloadobj.mat').x;
@Matt J true, so in that sense it is the same as loading via matfile().x but not as load(..,'x'):
disp('load only x');
s = load('toomanyloadobj.mat','x');
disp('load only x 2');
x = load('toomanyloadobj.mat').x;
->
load only x
load only x 2
->constructor
->loadobj
Of course, this is because load('') loads the entire contents of the mat file, no surprise there.
Why are you defining the loadobj method for your class? Without it you do not see the issue. Having loadobj seems to be overriding the default constructonload attribute of the class?
@Jeffrey Clark because my class has a nested structure, such that the shallow copy given by the default loadobj() (called by load()) method is not sufficient. In any case, "without it you do not see this issue" - true, I don't see it, but it still happens - loadobj() is called as part of the load/save methodology provided by MATLAB.
I am now thinking that perhaps one solution would be to create a class and method that overloads matfile(), such that when I call mymatfile().x it performs a specific load(...,'x'), so only of 'x'. Same with save(...,'x','-append'), or something like that. Unless there's some way to solve this with MATLAB's built-in functions.
I hope you've submitted this as a bug report.

Sign in to comment.

Answers (1)

Hi Roys,
I understand that you are facing an issue where the “loadobj” function is being called every time you access the contents of a saved “matfile”, even if you only want to retrieve a specific variable.
To address this, you can use the “load” function with the specific variable name to directly load only the desired variable without triggering the “loadobj” function.
Here is a sample code for accessing a variable without triggering the “loadobj” function:
% Create a sample class with loadobj() function
classdef toomanyloadobj
methods
function obj = toomanyloadobj()
disp('->constructor');
end
end
methods (Static)
function obj = loadobj(s)
obj = toomanyloadobj(); % must return obj with this class
disp('->loadobj');
end
end
end
% Save the object and variable to a matfile
x = 15;
obj = toomanyloadobj();
save('toomanyloadobj.mat', 'obj', 'x');
% Load only the variable 'x' using load()
s = load('toomanyloadobj.mat', 'x');
disp("loaded first time " + s.x);
s = load('toomanyloadobj.mat', 'x');
disp("loaded second time " + s.x);
By using “load('toomanyloadobj.mat', 'x')” you can directly load the variable 'x' without invoking the “loadobj” function. Please note that while using the “load” function with the specific variable name can bypass this issue, it may not be possible to prevent “loadobj” from being called when using “matfile”.
Here is the output observed with the above modification (“loadobj” is not invoked every time):
->constructor
loaded first time 15
loaded second time 15
Refer to the documentation of “load” and “matfile” functions in MATLAB for more information.
Hope this helps!

1 Comment

The specific requirement is to be able to use matfile without the object being constructed before it is requested. Using load() with a specific variable name does not solve the problem

Sign in to comment.

Asked:

on 9 Apr 2022

Commented:

on 16 Oct 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!