How to make calls to static methods independent of packaging structure (name)?

조회 수: 4 (최근 30일)
Robert Borkowski
Robert Borkowski 2022년 12월 12일
답변: Walter Roberson 2022년 12월 16일
Hello,
I have the following class:
classdef TestStaticMethodPackage
methods (Static)
function hello
fprintf("Hello world\n");
end
function write
TestStaticMethodPackage.hello;
end
end
end
I run it:
>> TestStaticMethodPackage.write
Hello world
I am now trying to organize my code into a package:
>> !mkdir +TestPackage
>> !move TestStaticMethodPackage.m +TestPackage\
Trying to run now:
>> TestPackage.TestStaticMethodPackage.write
Unable to resolve the name 'TestStaticMethodPackage.hello'.
Error in TestPackage.TestStaticMethodPackage.write (line 9)
TestStaticMethodPackage.hello;
This behavior breaks essentially all static methods, and requires the classes to be aware of their external environment. Is there a simple workaround to make it flexible to work in any package structure without having to change all calls where static methods are used?
I was thinking about writing some static method launcher based on dbstack and eval but what's making things worse is that dbstack does not see the package name in front of the class name. Adding the following line before TestStaticMethodPackage.hello; line in class definition:
s = dbstack('-completenames')
results in:
s =
struct with fields:
file: 'C:\...\+TestPackage\TestStaticMethodPackage.m'
name: 'TestStaticMethodPackage.write'
line: 9
'name' seems inconsistent, since even within the class itself I need to prepend package name to class name to call a static method.
  댓글 수: 2
Jiri Hajek
Jiri Hajek 2022년 12월 14일
Hi, it seems that you want to run code that is not on the MATLAB path. It is not clear why you should want this, as you can easily "addpath", if its really important for you. You want to build a compiled app and be able to run it anyway or what is the purpose of this?
Also, you are using funny name for your directory (note the "+" sign within the folder name. Matlab is generally sensitive about special characters on the path.
Robert Borkowski
Robert Borkowski 2022년 12월 14일
편집: Robert Borkowski 2022년 12월 14일
Hi Jiri, + is not a "funny name". It is a prefix used to identify a package directory https://www.mathworks.com/help/matlab/matlab_oop/scoping-classes-with-packages.html Packages cannot be added to path using addpath.

댓글을 달려면 로그인하십시오.

답변 (2개)

chrisw23
chrisw23 2022년 12월 13일
try to set a session path (addpath) and import the package path (i.e. import MyPackageRoot.TestPackage.*)
  댓글 수: 2
Robert Borkowski
Robert Borkowski 2022년 12월 13일
편집: Robert Borkowski 2022년 12월 13일
Hi Chris,
That's not really a solution. In the example above I only have one level of packages: TestPackage, which already is in the working directory.
After running import TestPackage.* I can then of course make calls in the current scope, but it does not solve the fundamental problem of calls to static member method inside of the same classdef, which happen in the scope of another static member method:
>> import TestPackage.*
>> TestStaticMethodPackage.write
9 TestStaticMethodPackage.hello;
Unable to resolve the name 'TestStaticMethodPackage.hello'.
Error in TestPackage.TestStaticMethodPackage.write (line 10)
TestStaticMethodPackage.hello;
The only way I can to solve this problem is to make changes in each and every static method, and do a dynamic import that will include potential hierarchy of pacakges names. It seems to be "broken by design".
chrisw23
chrisw23 2022년 12월 16일
편집: chrisw23 2022년 12월 16일
Path ..MatLabClassExample\+TestPackage\@TestStaticLibrary
TestScript at MatLabClassExample dir
import TestPackage.*
str = "direct static call: " + TestStaticLibrary.hello()
myStaticLib = TestStaticLibrary();
str = "indirect static call: " + myStaticLib.write()
classdef TestStaticLibrary < handle
events
% requires handle super class
end
properties (SetAccess = public, GetAccess = public)
% to be defined
end
methods (Access = public)
function obj = TestStaticLibrary()
% construcor
end
function delete(~) % ~ replaces unused obj argument here
% destructor
end
%% my public methods
function str = write(obj)
str = obj.hello;
end
end
%% private methods
methods (Access = private)
end
%% static methods
methods (Static)
function str = hello
str = "Hello world";
end
end
end

댓글을 달려면 로그인하십시오.


Walter Roberson
Walter Roberson 2022년 12월 16일
Known work-arounds:
  • preprocessing the source code to convert some kind of relative reference to absolute reference before executing
  • pass down the package names in calls so that you can dynamically generate the import statements (does not play well with compilation)

카테고리

Help CenterFile Exchange에서 Construct and Work with Object Arrays에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by