How to shadow the built-in find function
Ältere Kommentare anzeigen
A while ago I have written a FEX submission that extends the capabilities of find to also work for 3D and up: findND (e.g. a syntax like [x,y,z,val]=findND(A)).
I would like to be able to shadow the built-in function, so I have the option of simply using [x,y,z,val]=find(A) in my code. My function would then use the code from this previous question to get a handle to the built-in function, so my function catches the call to find and does its thing if it needs to. Based on this question, I would have thought that it would be relatively easy to do this: just ignore the warning.
However, when I try this, it doesn't work: Matlab still calls the built-in function. list = which('find', '-all') shows my function as the first entry (for R2017b and R2012b).
It makes sense that Matlab would use the built-in, as that is the function precedence order, but in that case I don't understand why which would think that the local function would take precedence.
Is there a way to do this (preferably without requiring the end-user to jump through many hoops), or should I give up and just use my function under its own name?
22 Kommentare
Rik
am 5 Mär. 2018
John D'Errico
am 5 Mär. 2018
Weekends are slow.
Stephen makes good points here. Keeping them separate makes things simpler, and has many advantages. One more advantage is that the built-in find becomes a bit slower when you did just want to use it after all. Now you would have an additional layer of function overhead, tests, etc.
I would also add that the usual solution used, instead of needing a tool that grabs find as a function handle, is to use the builtin function. So at the point where you realize you really wanted to call the default find, just call it as
varargout = builtin('find',varargin{:});
That should grab the old find. What would not surprise me is if you needed to use the rehash command to make sure MATLAB sees your new find tool on the search path. If you don't use rehash, then even though which see your find, the toolbox cache is what matters in terms of what function is actually called.
Now, interestingly, I tested this all out with my own test version of find to see if I could overload find. My version of find just displayed some text to the command line, then used the function builtin to call find.
Assuming I would need to rehash the path, I did that, yet rehashing the cache, even restarting MATLAB, all failed to use my own version, consistent with what Rik observed.
Rik
am 5 Mär. 2018
Well, here I am years after this thread was opened with the exact same problem. In my case, there's a toolkit that has 1000+ files calling a builtin function I want to override/shadow. which -all tells me I've shadowed it. I've rehashed the toolbox. I've cleared the function cache. But MATLAB insists on calling the builtin, depsite me telling it, and it telling me, that my function has precedence. Bummer.
Matt J
am 1 Sep. 2026 um 20:10
If all 1000+ files are in the same parent folder, you could put your legacy version of the function in a private folder
You could also rename the function and do a multi-file search/replace to replace all the calls,
Michael
am 1 Sep. 2026 um 22:55
There are hundreds of directories containing thousands of files. And the goal is for a community of thousands of users to be able to either use the builtin functions (as normal) or activate the overlay for specific reasons. It's wild that MATLAB tells me one thing (via which -all) and then does something else.
Hi Michael,
Create a find.m and then check which -all
writelines(["function y = find(x)";"disp(""hello"")";"end"],"find.m");
which('find','-all')
The shadowed function is /MATLAB/toolbox/matlab/elmat/find.
Here on Answers, we can't see the contents of that file
try
type /MATLAB/toolbox/matlab/elmat/find.m
catch ME
ME.message
end
On my local installation, elmat/find.m only includes the help for find.
But when we actually try to execute find
x = [1:2];
find(x)
which find(x)
We see that we are actually getting the object function for the double class (at least I think that's what that means), which, according to Function Precedence Order - MATLAB & Simulink, has precedence 7 whereas functions in the current folder have precedence 9.
Does your function have the same name as an object function that is not the actual function that is being shadowed?
"And the goal is for a community of thousands of users to be able to either use the builtin functions (as normal) or activate the overlay for specific reasons."
I certainly would not rely on fragile, class-and-version dependent shadowing for this goal. Much better code design: passing a function handle, or setting a flag, or calling a thin-wrapper, or some other robust approach.
Rik
am 2 Sep. 2026 um 15:00
For the example at hand where the current directory contains the file find.m ...
what specifically do you think
which('find','all')
should return to the screen if it worked the way you expect it to work?
Rik
am 3 Sep. 2026 um 10:06
I have some concerns about the doc and how Matlab works that I might come back to later.
In the meantime .... if you expect
which('find','-all')
to produce the function precedence, why must @char/find have precedence over @double/find ? Is char higher than double on some ranking of Fundamental Matlab Classes? More generally, what determines precedence among all of the entries in the output of which('find','-all')?
Sidebar not relevant to this discussion ...
I just noticed something strange. On my local installation (R2024a) the output of
which find -all
shows @sym/sym.m immediatley prior to @mtree/mtree.m. But I don't see @sym/sym.m anywhere on the output list above. find is a method of the sym class
ismember('find',methods('sym'))
so I don't undertand why it's not found by which. But it is found if using an output argument of which
s = which('find','-all');
s(contains(s,'sym'))
@Paul: based on eyeballing, the elmat/@<class>/find functions are sorted exactly into ASCIIbetical order. Which implies that the order within each such group is merely a display artifact, and not related to function precedence.
Paul
am 3 Sep. 2026 um 14:47
@Stephen23 can you figure out the ordering rule for the entire list?
I don't think it's possible for the list to be ordered by function precedence, which is why I am curious about why @Rik thinks it should.
Re: @sym/sym not showing up at first:
As stated on this documentation page, the class definition for sym is not loaded into memory when MATLAB starts up. It's not needed. So until that definition is loaded, which isn't going to find that method name if the method is defined inside the class definition file. Methods defined as separate function files in the @sym class directory are visible; they're files on the file system.
Start a new session of MATLAB and run:
which -all assume
MATLAB lists the file in @symfun, since that's a method defined in a separate file. Now create a sym object and try that again.
syms x
which -all assume
Now MATLAB shows two functions, one the file in @symfun and one the method defined inside the class definition file for sym. Creating the sym object (by calling syms, which calls the sym constructor) forces MATLAB to load the class definition and now the method defined in that file is visible.
@Paul: It is listed in order of precedence, just as the WHICH documentation states. The only complication is that WHICH can include functions of equal precedence because they apply to different classes. Compare:
x = single(32);
which find(x) -all
x = double(32);
which find(x) -all
x = char(32);
which find(x) -all
etc. Within those groups of equal precedence any display order could be used (AFAICT for files ASCIIbetical and for built-ins in the order of some LUT), because they have no inherent order.
I guess we are now at the nexus of which, Function Precedence Order - MATLAB & Simulink, and built-in functions.
The doc page which only states that the output of which is FPO when returning to an output argument when using the function form. It's probably safe to assume that the command form is the same, though it wouldn't hurt for the doc page to say so, insofar as that there are differences between calling which with and without an output argument (and it seems the command form displays the same results as the latter).
As we've seen
s = which('find','-all');
s{1}
In R2024a on Windows, elmat/find.m is an ordinary m-script. But that's not the case as far as I can tell in R2026a here on Answers and Online (are those implmenations different than Windows?). Perhaps something has changed over the last two years? Nevertheless, why exactly is elmat/find returned first? I mean, it's not actually a function that can be executed (AFAICT), so why is it first on the list, allegedly in accordance with FPO?
If we create find.m in the current folder, wouldn't our find.m have lower precedence than every other implementation of find? Yet it's returned first as shown above.
In this case
which('find(1)','-all')
why is the mysterious elmat/find returned at all? After all, this usage is to "Display the path to the implementation of function fun which would be invoked ..." Insofar as only one function can ever be invoked, I don't understand why the form of that call to which can ever return more than one result, much less a result that, for all intents and puposes besides help, doesn't exist (certainly not as a function to be invoked).
I also find it interesting that term "Function" in FPO refers to more than functions. After all, the item with highest precedence is "Variables"! FPO also applies to (among others) "program files with a .m extension", which also aren't functions. Furthermore, FPO also
"considers the file type, in this order:
- Built-in function
- ...."
But I've understood forevere that a built-in function is not implemented in a file. According to builtin "A built-in function is part of the MATLAB® executable." (emphasis not added). I think what the doc means to say is that a built-in function has precedence over the file types starting at 2, but it certainly reads like a built-in function has a file type.
WHICH indicates a built-in function by at least three different formats.
s{[2,15,46]}
Is there anything important (or even not important) to be gleaned from these different formats?
Rik
am 4 Sep. 2026 um 10:01
When I typed that statement I was thinking that the concept of function precedence order applied only at execution time, i.e., to determine which function should be called when a line of code is being evaluated when used in command, just as you say. In that context,
which find -all
isn't actually executing a find command(*), in which case function precedence order doesn't apply. Furthermore, as alluded to and then discussed above, there is no precedential ordering between, for example, @double/find and @int64/find. They both fall under category 7 - object functions. So how can which sort those two by function precedence? I think that question was also clattering around inside my head when I typed that statement.
Since I typed that statement and reading subsequent comments, I now understand better what WHICH is trying to do, even though it seems to do it incorrectly at times as you indicated in this comment.
Perhaps the doc page for which should say that the output is sorted according to categories of FPO, and within each category of FPO the sorting is alphabetical (or whatever).
(*) To determine the specific function that will be called at execution time, I just use
which find(X) % or which('find(X)')
Since I learned about that usage (thanks to @Steven Lord !) I rarely, if ever, have the need for which -all. And I never have used which('find(X)','-all'), since the -all should be superfluous.
Akzeptierte Antwort
Weitere Antworten (1)
Shadowing functions included in MATLAB can be dangerous, because it can affect the functionality of other functions. In the best case scenarios, the functionality will work the same way as the function included in MATLAB. In the next best, it will throw a hard error. In the worst case scenario, it will behave almost the same as the function you're shadowing but silently give the wrong answer. These types of problems can be very difficult to detect.
Consider the rand function. If I generate a histogram of the results, it should show uniformity.
histogram(rand(1, 1e6))
xlim([0 1])
Let's make a new rand that generates biased numbers, numbers that only span 0.25 to 0.75.
T = tempname;
mkdir(T)
addpath(T);
fid = fopen(fullfile(T, 'rand.m'), 'wt');
fprintf(fid, "function y = rand(varargin)\n" + ...
"y = 0.25 + 0.5*builtin('rand',varargin{:});");
fclose(fid);
rehash toolboxcache
Are we using the new rand?
which rand
What does the histogram look like?
histogram(rand(1, 1e6))
xlim([0 1])
Now suppose you called rand as part of a Monte Carlo simulation. Might the results of that Monte Carlo simulation be invalid if you assumed it generated numbers between 0 and 1 and it didn't?
Kategorien
Mehr zu Function Creation finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

