Nested Structures Vrs. Class objects

17 ビュー (過去 30 日間)
John H.
John H. 2023 年 2 月 23 日
コメント済み: Walter Roberson 2023 年 3 月 2 日
Hello all,
I am writing a gui which controls external hardware thru an interface protocol.
Currently i defined all my control commands into a structure with common read and write functions that are called via function handles.
This works great!
Except to get it to work the way I wanted it to work i needed to use a global variable, and dynamically define a variable. Both of which everyone tells me I am a horrible person for doing.
But i successfully impletmented this with 50 or so Commands for several 'B' level module units, i can call each command just by typing the desired structure element .in this example CallOutput = A.B.C1(1,4) will perform my hardware call and set A.B.C1 to the same value simultaneously.
Thus allowing me to avoid typing 5 or 6 lines of code in the main script everytime i want to issue a command or pull a state from the hardware.
But also allowing me to just define the parameters of each command in the structure then pass those parameters to the read function, rather than haveing to write a different read function for each command.
function StructureTest
global A
A.B.C1 = 0;
A.B.C2 = @(x,y) Test(x,y,A,'B','C1');
A.D.C1 = 0;
A.D.C2 = @(x,y) Test(x,y,A,'D','C1');
CallOutput1 = A.B.C2(1,4)
disp(A.B.C1)
CallOutput2 = A.D.C2(5,6)
disp(A.D.C1)
end
function Z=Test(X,Y,A,Module,Command)
global A
Z=X+Y;
A.(Module).(Command) = Z
end
While this works, the issue i face now is that matlab shows
"Warning: The value of local variables may have been changed to match the globals. Future versions of MATLAB will require that you declare a variable to be global before you use that variable. "
A) I recognize using a global is not the best of ideas
B) i dont want to get scewed later if matlab changes how the globals work
So now you have the background, lets get to my actual question.
It has come to my attention that i can maybe create a class and achieve the same functionality, but without the use of globals.
however, I am struggling with determining how the class functionality mirrors the structure/functionality I have already created.
I really like my ability to call what i need in the form of a structure, where the commands all together, but segregated into their own related groupings via different levels of the structure.
Classdef seems to have a single layer of depth within it while my structure has multiple layers A.B.C, etc.
Creating a subclass seems to want me to create a new file.
I am simply not seeing how i can translate my current structure into a class.
Do i need to define a new classdef file for everysingle command i need to use? (that would be C level in the above example code?) this would result is hundreds of individual files.. Which doesnt seem like the way its supposed to work. Thus i must be missing something.
Can someone help me by looking at the above code and indicating how it could be re-written into a class?
Once i see an example of what i need to do, i should be able to carry myself the rest of the way. its just this first step i cant wrap my brain around.
  3 件のコメント
John H.
John H. 2023 年 2 月 23 日
Ahhh,
So thats why it does that. thank you for clearing that up for me.
I gave it a shot and discovered that the function call
A.B.C2 = @(x,y) Test(x,y,A,'B','C1');
Takes the A structure and "preserves" it at that point in time in which the funtion handle was created, then passes the old version to the function, which overwrites A when you call A=Ap.
Solution was to simply not pass A at all and rely on the global nature of global A.
A.B.C1 = 0;
A.B.C2 = @(x,y) Test(x,y,'B','C1');
function Z = Test(X,Y,Module,Command)
global A
Z=X+Y;
A.(Module).(Command) = Z
end
since im not calling A prior to declaring global, it doesnt give me the error message and A being global remains the most recent version of A.
Thanks for the tip!
The question remains, should i keep my architecture as is, with the global and dynamic variable name.
Or should i continue down the path of trying to create a class specific to my whole hardware communication protocol and port the strutcture into a class.
chrisw23
chrisw23 2023 年 2 月 24 日
編集済み: chrisw23 2023 年 2 月 24 日
I change my code any time I get warnings about the use of deprecated functions, because I don't want to stay with an old version of Matlab. BTW OOP with Matlab is easy and comfortable...much better than any Global var...(my opinion)
Or should i continue down the path of trying to create a class specific to my whole hardware communication protocol and port the strutcture into a class.
YES

サインインしてコメントする。

回答 (1 件)

Aditya Srikar
Aditya Srikar 2023 年 3 月 2 日
Hi John
You can use class instead of using global variables and C-style functional programming. Class is more efficient way of writing programs and it provides code refactoring, reusability and access control mechanisms. If too many variables are declared as global, then they remain in the memory till program execution is completed. This can cause of Out of Memory issue. Any statement written in the program can change the value of the global variable. Data can be modified by any function and global variable stores the most recently updated value.
You can refer this documentation for more details about creating a class
  1 件のコメント
Walter Roberson
Walter Roberson 2023 年 3 月 2 日
"Class is more efficient way of writing programs"
Unfortunately, classes are seldom a more efficient way of executing code. The overhead of classes is often fairly noticeable.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeFunctions についてさらに検索

製品


リリース

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by