- Use a dummy import statement like import('STUB') where needed, and replace these with import('my_movable_package.*') using an init.m script.
- Place this script in the package's root folder to recursively update all files with the correct fully qualified paths.
Future-proofness of my relative import solution?
16 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
I am trying to solve the "relative-import" problem (import statements need to be absolute which makes using packages as subpackages in other packages hard).
I am solving this with a helper function located in the private-folder that is called `get_import_str`
function [import_str,parent_dir] = get_import_str()
% Returns the import string needed to import all sub-packages
%
% Usage: Place in the top of a package function to provide a relative import
%
% function out = functionA(arg1,arg2)
% % Package function located in <some_path>/+<some_package1>/+<some_package2>/
% % Import subpackages
% import_str = get_import_str();
% import(import_str);
%
% arg3 = functionB(arg1); % Sibling function
% out = arg1+arg2+arg3;
% end
%
stack_info = dbstack('-completenames');
if length(stack_info) <= 1, error('This function must be called from a m-file.'); end
caller_fn = stack_info(2).file;
[parent_dir,fname,~] = fileparts(fileparts(caller_fn));
while true
if ~strcmp(fname(1),'+')
parent_dir = fullfile(parent_dir,fname);
import_str = fileparts(caller_fn);
import_str = [replace(import_str(length(parent_dir)+3:end),[filesep,'+'],'.'),'.*'];
return
end
[parent_dir,fname,~] = fileparts(parent_dir);
end
end
To call a sibling package function you use the
function out = functionA(arg1,arg2)
import_str = get_import_str();
import(import_str);
arg3 = functionB(arg1); % Sibling function: Returns arg1*10
arg4 = sub_package.functionC(arg2); % Child-package-function: Returns arg2*pi
out = arg1+arg2+arg3+arg4;
end
This seems to work fine (please inform me if you se any issues) but now to my question:
Question: How future-proof is this? I get a warning saying
"In a future release, IMPORT will not accept variable names, function calls, or operators. Use literal char vectors instead."
At my company we run a old version of matlab (R2018b) but I don't want my stuff to break when we upgrade.
Details
<some-path>
+my_movable_package
private/
get_import_str.m
functionA.m
functionB.m
+sub_package
functionC.m
0 Kommentare
Antworten (1)
Arnav
am 7 Nov. 2024 um 11:02
To avoid deprecation warnings when using import function dynamically, switch to using fully qualified path names in the import statement. Alternatively, you can replace import statements statically before any function execution.
You can refer to the below:
To recursively find all .m files in a package you can use the code snippet shown:
function INIT()
script_full_path = mfilename('fullpath');
[package_root, ~, ~] = fileparts(script_full_path);
files = dir(fullfile(package_root, '**', '*.m'));
for k = 1:length(files)
file_path = fullfile(files(k).folder, files(k).name);
if strcmp(files(k).name, 'init.m')
continue;
end
replace_stub(file_path, package_root);
end
end
function replace_stub(file_path, package_root)
fid = fopen(file_path, 'r');
file_content = fread(fid, '*char')';
fclose(fid);
relative_path = strrep(file_path, [fileparts(package_root), filesep], '');
relative_path = fileparts(relative_path);
package_path = strrep(relative_path, ['+', filesep], '');
package_path = strrep(package_path, '+', '');
package_path = strrep(package_path, filesep, '.');
import_statement = sprintf("import('%s.*')", package_path);
new_content = strrep(file_content, "import('STUB')", import_statement);
fid = fopen(file_path, 'w');
fwrite(fid, new_content);
fclose(fid);
end
INIT();
This package can then be imported and used as shown below:
>> import my_movable_package.*
>> init
>> functionA(10, 12)
>> functionB(10)
0 Kommentare
Siehe auch
Kategorien
Mehr zu Historical Contests finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!