Anonymous functions saved as variables cannot be loaded while parent script has errors
5 views (last 30 days)
Show older comments
short summary
I save anonymous function handles in variables so I can access both my data and the functions for plotting them, but it appears that MATLAB stores info about where the function was created and attempts to re-load it from there. If I manage to load it, I can remove the link and the anonymous function works as intended, but otherwise it will somehow try to run my script where the function was defined and crashes if that script is not working (e.g. when I'm writing code in it). But I can remove that link and the function appears to run just fine.
In my main file M5_hga_features_and_power.m, I create an anonymous local function handle named title_fun(S,fb)
function correlate_pow_in_hga_absolute_weights
...
fname = {'delta', 'theta', 'alpha', 'beta', 'gamma'}; %frequency band names
A.mydata = somedatathatihave;
A.title_fun = @(S,fb) title(sprintf('subject %d, frequency band %s', S, fname{fb}));
save('mylocaldata', '-struct', 'title_fun', etc...);
...
end
Then I have another function which loads data and plots it
function plot_my_data
for S=1:2 %loop through my test subjects
for fb = 1:5 %loop through the frequency bands
A = load('mylocaldata', 'title_fun', etc...);
figure; plot(A.mydata);
A.title_fun(S,fb);
end
end
It is very convenient to have a title-function handle saved together with the data I want to plot and generally works fantastic. I can just loop through subjects and frequency bands and use these indices for my anonymous function without having the long formatting in the plot function. However, if I load 'mylocaldata' while having errors in my script file 'M5_hga_features_and_power.m', then the load-function gives me this error:
Error using load
Error: File: M5_hga_features_and_power.m Line: 166
Column: 1
Function definitions in a script must appear at the end
of the file.
Move all statements after the
"correlate_pow_in_hga_absolute_weights" function
definition to before the first local function definition.
It appears that when I load 'mylocaldata', the function handles somehow tries to access the script file (M5_hga_features_and_power.m) where I defined the anonymous function. I ran s = functions(A.title_fun), and found that it had saved the path to my script file.
s =
struct with fields:
function: '@(S,fb)title(sprintf('s%d %s mean hGA Weights (NFT sessions)',S,fname{fb}))'
type: 'anonymous'
file: '--long path--\analys\M5_hga_features_and_power.m'
workspace: {[1×1 struct]}
within_file_path: ''
But I don't need that path. If I clear it (set it empty), then I can load 'mylocaldata' without any errors, and the frequency band names are saved in 'workspace'. So my questions are:
- why does the anonymous function try to run the original script when I load it from a file? Does it try to update the function?
- Where is the information for the function handle saved? i.e. is the workspace variable somehow saved with the handle in my 'mylocaldata'-file?
I haven't found an answer on mathworks documentation on 'functions', 'Create Function Handle', 'Function Handles', 'Anonymous Functions' or other similar sites on mathworks website.
Also, if this kind of coding is crazy and you have a better idea for keeping functions with data, I'll gladly take your advice.
Kind Regards, Jonatan Tidare
1 Comment
Stephen23
on 12 Jul 2022
"if this kind of coding is crazy and you have a better idea for keeping functions with data, I'll gladly take your advice."
If storing a function handle is good for your workflow, then go for it. The fact that TMW probably has a bit more work to make that happen... well, so be it. Of course any data type has some special edge-cases, as you are finding out :)
Accepted Answer
More Answers (2)
Steven Lord
on 13 Jul 2022
But I don't need that path.
Prove that statement using static analysis, just looking at the contents of the struct array s.
I know what you're probably going to say, that it's obvious. But it's not if you look at it through the eyes of MATLAB. Here's your anonymous function:
@(S,fb)title(sprintf('s%d %s mean hGA Weights (NFT sessions)',S,fname{fb}))
How do you know that there was no local function or private function named either title or sprintf in scope at the time this anonymous function was created? Remember, if you "don't need that path" you can use neither the contents of the file in which that anonymous function was defined nor what's in that directory (including whether or not there's a private subdirectory or a title.m or sprintf.m in the directory that shadows the title or sprintf functions built into MATLAB) in your answer.
The alternative is to never let the m-file that created my anonymous function break (i.e. don't develop that file), which is what I will do for now.
I agree with the first part of your statement but not your parenthetical aside. As long as your code is syntactically valid I would expect loading the function handle to work. And if your code isn't syntactically valid, you're not going to be able to run it so what good is it doing you?
3 Comments
Stephen23
on 14 Jul 2022
Edited: Stephen23
on 15 Jul 2022
"I know that I don't need the path in "file", because ..."
No, that is not static analysis:
Presumably MATLAB uses that information somehow, otherwise they probably would not be lugging it around with the function handle. Most likely this is a side-effect of a weakly-typed language.
See Also
Categories
Find more on Get Started with MATLAB in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!