image thumbnail

Workspace encapsulation object

version 1.0.1 (11.6 KB) by Benjamin Davis
This class creates an encapsulated workspace object to which scripts and other code may be applied without affecting the base workspace.

25 Downloads

Updated 29 Feb 2020

View License

Frequently it is desired to manipulate variables within a given MATLAB workspace conveniently in bulk, whether to emulate multiple workspaces, to cache variables without using a .mat file, or to pack/unpack variables from the fields of a structure. The following existing submissions provide some measure of this functionality.

Multiple workspaces without .mat save:
https://www.mathworks.com/matlabcentral/fileexchange/12522-multiple-concurrent-workspaces-updated-2

Copy current workspace to base workspace:
https://www.mathworks.com/matlabcentral/fileexchange/24121-save_to_base-m

Convert struct fields to variables (no assignin):
https://www.mathworks.com/matlabcentral/fileexchange/26216-structure-fields-to-variables

Pack/unpack struct fields to/from variables (with assignin):
http://www.mathworks.com/matlabcentral/fileexchange/31532-pack---unpack-variables-to---from-structures-with-enhanced-functionality
https://www.mathworks.com/matlabcentral/fileexchange/57370-struct2vars
https://www.mathworks.com/matlabcentral/fileexchange/57371-vars2struct

This submission combines many of the ideas in these existing submissions into a single framework, but also adds the following new features:
- Object-oriented encapsulation of workspace state
- Global variable packing/unpacking
- Save/load of encapsulated workspace state to/from .mat file
- Execution of code and scripts within the context of a captured workspaces state rather than the main workspace.

The last feature I consider to be especially novel and useful. It does not seem to be part of any other submission I have found. This feature allows encapsulation of the execution results of a script from the controlling workspace.

Here is a highlights demo of the feature set.

%Do some things in the workspace
a = 1;
b = 'hello';
global c
c = 10;
c12 = 'foo';

%Pack all these up into an object
ws = Workspaces.pack();

%This workspace can then be saved in a memory store
Workspaces.store('myws', ws);

%Even if the base workspace is cleared
clear
clear global

%the workspace can be retreived
ws = Workspaces.recall('myws');

%and unpacked
ws.unpack();

%so now all the values are back
disp(a)
1
%including the global
whos global
Name Size Bytes Class Attributes

c 1x1 8 double global

clear
clear global

%variables can be partially unpacked
ws.unpack('a', 'b');

%this supports unpacking all except a list
ws.unpack('-not', 'c');

%and also regexp notation
ws.unpack('-regexp', '^[b-d]')

%or all except a regexp
ws.unpack('-notregexp', '^c\d+')

%We can also unpacked using function outputs
[a, c12] = ws.get('a','c12');

%or explicitly by using the object properties
a2 = ws.variables.a;
c2 = ws.globals.c;

%If the object has many vars, we can request a code string to do
%the unpacking so we don't "poof" variables with evalin
ws.unpack_code('ws') %the output is auto-copied to the clipboard as well
'a = ws.variables.a;
b = ws.variables.b;
c12 = ws.variables.c12;
global c
c = ws.globals.c;
'

%We can assign some of the variables from this workspace to another
ws2 = ws.select('a', '-regexp', '^c\d+');

%and update the workspace values from other structs or workspace objects
s.b = 5;
ws = ws.update(s); %this will update only vars that exist
disp(ws.get('b'))
5
s.f = 'bar';
ws = ws.update(s); %this will also add new variables
disp(ws.get('f'))
'bar'

%of course the variables can be updated through the properties
ws.variables.c12 = 13;
ws.globals.g = 20; %new global

%or set through the 'set' method
ws = ws.set('c12', 31, '-global', 'g2', 100); %another new global

%All these features were present in previous submissions in some form.
%(except the treatment of globals)
%But now the new features...
clear
clear global
ws = Workspaces.recall('myws');

%make an assignment involving variables inside the object
ws = ws.exec('a = a + 1')
%you can even make new variables this way
ws = ws.exec('d = 200')

%evaluate an expression using the workspace values
disp(ws.eval('10*a + d'))
220

%save the contents of the object to a .mat file
ws.save('myws.mat', '-v7.3', '-nocompression'); %the full set of save args are supported

%and load to another object
ws2 = Workspaces.load('myws.mat', 'c*') %again the full args to load are supported

%finally the piece de resistance
%the effects of entire scripts can be encapsulated within an object
ws = ws.run('script1.m'); %none of the polluting effects of script1 are visible in the base
ws = ws.run('script2.m'); %script2 depends on script1 results
%out of all the script run, we just wanted one result using a name we control
my_result = ws.get('result')

Cite As

Benjamin Davis (2022). Workspace encapsulation object (https://www.mathworks.com/matlabcentral/fileexchange/74388-workspace-encapsulation-object), MATLAB Central File Exchange. Retrieved .

MATLAB Release Compatibility
Created with R2019b
Compatible with R2016a and later releases
Platform Compatibility
Windows macOS Linux

Community Treasure Hunt

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

Start Hunting!