Over the years, there have been lots of questions about when MATLAB recognizes files on the path. Today I'm going to talk about the case where a user generates or updates MATLAB code, and then wants to use it. What do you have to do to be sure MATLAB sees it? I am specifically talking about user files in user directories and NOT about files underneath matlabroot.
Contents
function fcnPuzzle()Note: I am doing an experiment by publishing a function with subfunctions so you can see the code with the benefit of syntax highlighting for the code that's not the blog-code itself. I hope this ends up working and being helpful.
The Code That Perplexed
See the function fcnBug towards the bottom of this post. One puzzle is that if you run the code from the debugger, the results are always the expected ones, but not when running the usual way. I'll illustrate the conundrum by running it a few different ways. Also see the repaired version fcnBugRepair following the buggy version.
Show the file doesn't exist.
exist('fcnTest.m','file')
ans =
0
Small puzzle. If I don't put my first attempt, before the file exists, into a try-catch, my function fails with an error. However, if I place the same code inside a try-catch, it seems to not generate the error. Let's ignore that mystery for today.
try fcnBug( 'C', 'clear') catch ignoreException disp('error when file doesn''t exist before running') end
Only the original function written out is called, not the updated versions, assuming we do nothing else in the function to affect the workspace.
for d=1:4 fcnBug( num2str(d), 'nothing') end
1 Problem 1 Problem 1 Problem 1 Problem
Clearing the function before calling it helps.
for d=1:4 fcnBug( num2str(d), 'clear') end
1 Problem 2 Problem 3 Problem 4 Problem
Another way to influence MATLAB to see the new function is to ask if the file exists.
delete fcnTest.m for d=1:4 fcnBug(num2str(d), 'clear+exist') end
1 Problem 2 Problem 3 Problem 4 Problem
Clean up.
delete fcnTest.mFixing the Problem
There is an easy solution to being sure that the new file is recognized. Directly after closing the file, force MATLAB to clear the one in memory. You can do this with a lighter or heavier hand, depending on your situation. Simply clearing the function is enough, or you might try to rehash the files MATLAB knows about.
try fcnBugRepair( 'C', 'clear') catch ignoreException disp('error when file doesn''t exist before running') end
error when file doesn't exist before running
Let me show this working with the repaired function. This was the case earlier in which only the file originally written out was called. You can see here that each version is now executed, even when nothing additional is done (except the addition of the clear statement in the function code).
for d=1:4 fcnBugRepair( num2str(d), 'nothing') end
1 Problem 2 Problem 3 Problem 4 Problem
As before, clearing the workspace before execution still has the good effect.
for d=1:4 fcnBugRepair( num2str(d), 'clear') end
1 Problem 2 Problem 3 Problem 4 Problem
Again, the test for function existence also works.
delete( 'fcnTest.m'); for d=1:4 fcnBugRepair(num2str(d), 'clear+exist') end
1 Problem 2 Problem 3 Problem 4 Problem
Clean Up
delete fcnTest.mWhy Does This Solution Work?
The problem is that of timestamp resolution for the file, which on most filesystems is only 1 second. Since this is being run in a tight loop, the file fcnTest.m is being rewritten during the same clock tick and therefore MATLAB has no way of knowing that it has changed. Therefore, MATLAB originally continued to use the cached version.
clear forces MATLAB to dump its cache, and the next time MATLAB runs the function it reloads it from disk.
The functions exist and rehash each cause MATLAB to notice the file change because they each refresh "dirty" directories.
The reason MATLAB doesn't always look for changes is for performance. fclose does notify the path manager that a certain directory is changed but the cache update won't happen until someone explicitly refreshes the directory -- the refreshing can happen in the ways I've already discussed, or at the next command prompt (that is why it works in debugger).
Original Function
function fcnBug( id, mode)% fcnBug - unexpected bug % % %% Error % % when the file does not exist before run % fcnBug( 'C', 'clear') % %% Only the 'base workspace one' % % is called % for d=1:4 % fcnBug( num2str(d), 'nothing') % end % %% Clear the workspace % % helps % for d=1:4 % fcnBug( num2str(d), 'clear') % end % %% Not at creation time % delete( 'fcnTest.m'); % fcnBug( num2str(1), 'clear') % %% Exists % % seems to tell to MATLAB that a function is here % delete( 'fcnTest.m'); % for d=1:4 % fcnBug(num2str(d), 'clear+exist') % end fid = fopen('.\fcnTest.m', 'w'); fprintf(fid, 'function fcnTest(varargin)\ndisp(''%s Problem'')', id); fclose(fid); switch lower(mode) case 'clear+exist' clear fcnTest exist( 'fcnTest.m', 'file'); case 'clear' clear fcnTest case 'nothing' end fcnTest;
error when file doesn't exist before running
Repaired Function
function fcnBugRepair( id, mode) % Repaired by adding clear statement in a good location fid = fopen('.\fcnTest.m', 'w'); fprintf(fid, 'function fcnTest(varargin)\ndisp(''%s Problem'')', id); fclose(fid); clear fcnTest % or could use rehash here instead switch lower(mode) case 'clear+exist' clear fcnTest exist( 'fcnTest.m', 'file'); case 'clear' clear fcnTest case 'nothing' end fcnTest;
Get
the MATLAB code
Published with MATLAB® 7.7



Maybe you can tell that I’m catching up on your old columns.
Anyway, I’m surprised that no one commented on this.
The topic title seems attractive, but I can’t follow anything about this.
What is the function fcnBug suppose to do? I’m guessing this is just to illustrate some subtle detail regarding the path precedence. But, I can’t figure out what the expected results of this function are.
What are the id & mode variables controlling?
Also, what is this fcnPuzzle?
And, where us this fcnTest.m? What does it do?
OysterEngineer-
fcnTest.m is a file that the user is writing out in the course of calculations. The point was to show how to, and how not to, write a new file out during the course of calculations so that it could get recognized and used later in the processing.
mode is controlling whether you clear or use exist to see if the function fcnTest is available. And you might use both.
id was used in the commented version of fcnBug so you could tell whether version 1, 2, 3, or 4 was the one being found (versus what you might expect).
To understand more details, which are a bit nuanced (and clearly I haven’t shown them well here), you could try experimenting with the code yourself. The nuances come from how you run the function and therefore get different results. If you run in the debugger, all is well. If you run in the normal fashion, you get issues because the file was cached and MATLAB doesn’t recognize there’s a new version without some intervention. clear is the way to go, but it matters where/when you perform the clear.
The main thing to notice is the use of clear near the top of the repaired function. That is the key to getting the new code recognized under all the different circumstances.
–Loren