| MATLAB® | ![]() |
| On this page… |
|---|
Modifying the Save and Load Process |
You can save objects to a MAT-file and then reload them into the workspace. In most cases, saving and loading objects from MAT-files is no different from working with other variables. However, you can modify the save and load process to better support class backward and forward compatibility.
You can define methods for your class that are executed when you call save or load on an object:
The saveobj method is called by save before performing the save operation. The save function then saves the value returned by the object's saveobj method. You can use the saveobj method to return a modified object or any other type of variable, such as a struct array.
The loadobj method is called by load before performing the load operation. The load function loads into the workspace the value returned by the object's loadobj method. Defining a loadobj method gives you the opportunity to modify the object being returned.
If you implement a saveobj method that modifies the object being saved, then you probably need to implement a loadobj method to return the object to its proper state when reloading it. For example, you might want to store an object's data in a struct array and reconstruct the object when reloaded to guard against the possibility that the class definition might change.
Saving objects in MAT-files saves the following data:
The names and values of all properties not marked as Transient or Constant (See Specifying Property Attributes for a description of these attributes.) However, to decrease file size, property values are saved only if they differ from the default values specified in the class definition.
All property initial values
The full name of the object's class, including any package qualifiers.
Even if your saveobj method saves only the object's data in an array and not the object itself, the object's class name is saved so that load can determine which loadobj method to call.
If the class's ConstructOnLoad attribute is set to true, then the load process calls the class constructor with no arguments and creates a new object of the class using the data stored in the saved object. When loading objects from MAT-files the load function does the following:
First reassigns the initial values that were stored in the MAT-file
Then assigns saved values to those properties whose values were not the same as their initial values at the time the objects was saved.
Each of these assignments (initial value and saved value) calls the property set method, if one is defined for that property.
It is possible for an initial value to cause an error in a set property method (for example, the class definition might have changed). When an error occurs while an object is being loaded from a file, the MATLAB runtime returns the saved values in a MATLAB struct.
When an error occurs, your loadobj method is passed the struct instead of an object. The loadobj method must use the values in the struct to call the class constructor and create a new object.
You must implement the loadobj method as a static method because loadobj can actually be called with a struct or other data instead of an object of the class. The saveobj method is implemented as an ordinary method (i.e., calling it requires an instance of the class).
The following discussion on saving and loading objects refers to a BankAccount class. Use the following link to see the full code for this class.
When you load an object that has been saved to a MAT-file using the load function, the object's loadobj method is called, if it exists. Implementing a loadobj method enables you to apply some processing to the object before it is loaded into the workspace. This might be necessary in cases such as the following:
The class definition has changed since the object was saved and you need to modify the object before reloading.
A saveobj method modified the object during the save operation, perhaps saving data in an array to be more efficient, and the loadobj method must reconstruct the object based on what saveobj did.
In the following example, the loadobj method checks to see if the object to be loaded has an old, shorter account number and calls a function to return an updated account number if necessary. After updating the object's AccountNumber property, loadobj returns the object to be loaded into the workspace.
methods (Static = true) function obj = loadobj(a) accnb = a.AccountNumber; if length(num2str(accnb)) < 12 a.AccountNumber = updateAccountNumber(accnb); % update object end obj = a; % return the updated object end end
In this case, you do not need to implement a saveobj method and are using loadobj only to ensure older saved objects are brought up to date before loading.
The next section provides an example in which loadobj performs specific operations to recreate an object based on the data returned by saveobj during the save operation.
Suppose that you know class definitions are likely to change over time, but you want to be able to reload older data and create objects according to the most current class definition. One approach is to save the object's data in a struct, but not the object itself.
To use this approach, create a saveobj method to extract the data you want to save from the object and write this data into a struct, which saveobj returns to the save function. You must also implement a loadobj method to extract the data from the reloaded variable and use this data to create a new object.
The following example saves the data from a BankAccount object having two properties. saveobj saves the values of the AccountNumber and the AccountBalance properties in the struct variable A, which has field names that match the property names. saveobj then returns the variable A to be saved in the MAT-file by the save function.
methods function A = saveobj(obj) A.AccountNumber = obj.AccountNumber; A.AccountBalance = obj.AccountBalance; end end
Suppose that a new property is added to the BankAccount class and all saved BankAccount objects must be recreated using the new class constructor. To create a valid object, call the constructor using the data saved in the variable A and pass any other arguments required. Because you are calling the latest version of the constructor in the loadobj method, the very latest version of the objects is created.
In this example, a new property called AccountStatus was added to the BankAccount class. If the account balance is greater than zero, AccountStatus is set to open. If the account balance is zero or less, AccountStatus is set to overdrawnor to frozen.
This loadobj method calls the class constructor with the appropriate value for the new property after testing the data saved from the AccountBalance property.
methods (Static = true) function obj = loadobj(a) if A.AccountBalance > 0 obj = BankAccount(a.AccountNumber,a.AccountBalance,'open'); else obj = BankAccount(a.AccountNumber,a.AccountBalance,'overdrawn'); end end end
Using saveobj and loadobj to manage changes to class definitions probably requires you to update these methods with each modification to the class. For example, you might need to accommodate a mix of old and new BankAccount objects with the saveobj method.
methods function A = saveobj(obj) A.AccountNumber = obj.AccountNumber; A.AccountBalance = obj.AccountBalance if BankAccount.isPropertyOf(obj,'AccountStatus') A.AccountStatus = obj.AccountStatus; end end end
This class defines a static method that determines if a property exists for an object. isPropertyOf is used to determine if the object being loaded has the new AccountStatus property.
methods (Static = true) function tf = isaPropertyOf(anyobj,PropName) if ~isa(anyobj,'meta.class') mobj = metaclass(anyobj); else mobj = anyobj; end tf = false; for k=1:length(mobj.Properties) if strcmp(mobj.Properties{k}.Name,PropName) tf = true; end end end end
Note that you can also use this method to determine if a class defines a particular property without creating an instance. For example, this statement determines if the BankAccount class defines a property called AccountType:
BankAccount.isaPropertyOf(?BankAccount,'AccountType')
The ?BankAccount argument creates a meta.class object from the class name, and then checks the class definition to determine if the class currently defines the named property.
See Obtaining Information About Classes with Meta-Classes for more information on meta-class objects.
![]() | Defining Named Constants | Obtaining Information About Classes with Meta-Classes | ![]() |
| © 1984-2008- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |