MATLAB Answers

Julian
0

How do I invoke a shadowed core MATLAB function (not built-in) from an overloaded function of same name

Asked by Julian
on 14 Aug 2014
Latest activity Commented on by Julian
on 14 Aug 2014
In an application I wanted to add a calling jacket for MATLAB's print. I was trying to add a print option -dsvg which used the great resource plot2svg.m to print to .svg, while using MATLAB's regular print for all other cases.
If I name my function print() in my local project folder, I can shadow the main print function for this application only, but I cannot then call base MATLAB print inside my custom version of print. I had thought
builtin('print' ...)
would do the trick, but print is not built-in so cannot be accessed in this way. I could use run command which changes directory but that seems "dodgy" (one would want to use try-catch to preserve directory in the case of print failure, at least). I could give my function a different name, but then I have to locate and change every call to "print" in my app, which is exactly what I was seeking to avoid!
Is there an nice way of doing this? Any help gratefully received.

  0 Comments

Sign in to comment.

2 Answers

Answer by Julian
on 14 Aug 2014
 Accepted Answer

A colleague gave me this answer, which I have used. I put the following code into the top of my overlay function (print() in my case):
persistent shipped % stores a handle to the shipped MATLAB funtion of the same name
if isempty(shipped)
this = [mfilename '.m']; % the name of function in MATLAB we are shadowing
list = which(this, '-all'); % find all the functions which shadow it
f = strncmp(list, matlabroot, length(matlabroot)); % locate 1st in list under matlabroot
list = list{find(f, 1)}; % extract from list the exact function we want to be able to call
here = cd(list(1:end-length(this))); % temporarily switch to the containing folder
shipped = str2func(this(1:end-2)); % grab a handle to the function
cd(here); % go back to where we came from
end
The first time it is used it locates the base MATLAB function which is shadowed by the function containing the above code, and creates a handle to the base function which is available for all subsequent calls to use as needed.

  1 Comment

I really like this answer, I am going to remember this one :)

Sign in to comment.


Answer by Christopher Berry on 14 Aug 2014
Edited by Christopher Berry on 14 Aug 2014

Julian,
I think you had the right idea with the run command to call print, but use the fullpath instead of cd into the directory. You can also use matlabroot to keep your script portable as well:
printMatlab = fullfile(matlabroot,'toolbox','matlab','graphics','print.m');
run(printMatlab)
As long as the script (here just print) does not change the directory it is in, run will return to the correct working directory on success or failure, so you do not need to worry about using try-catch yourself.

  3 Comments

thanks for this, but I couldn't work this solution. I got an error message, e.g.
RUN cannot execute the file 'C:\Program Files\MathWorks\MATLAB R2013a\toolbox\matlab\graphics\print.m
-dpng'. RUN requires a valid MATLAB script
The problem with run is it takes a script reference not a function, and does not accept arguments. The approach taken (below) is similar to run but grabs a function handle.
You are right, without arguments print is not all that useful. I was looking for a way around this when I saw your post.
A subsidiary question emerges though, how might I reference the help in the base / shipped function? If I put "See also PRINT" in my print overlay, clicking it just echoes the help in my function, rather than produce the help for the shadowed function....

Sign in to comment.