Call a function that is not on the Matlab path WITHOUT ADDING THAT PATH
Asked Answered
M

5

17

I have been searching an entire afternoon and have found no solution to call in matlab a function by specifying its path and not adding its directory to the path.

This question is quite similar to Is it possible to call a function that is not in the path in MATLAB?, but in my case, I do not want to call a built-in function, but just a normal function as defined in an m-file.

I think handles might be a solution (because apparently they can refer to functions not on the path), but I again found no way to create a handle without cd-ing to the directory, creating it there and the cd-ing back. Trying to 'explore' what a function handle object is and how to make one with a reference to a specific function not on the path has led me nowhere.

So the solution might come from two angles:
1) You know how to create a handle for an m-file in a specific directory.
2) You know a way to call a function not on the matlab path.

EDIT: I have just discovered the function functions(myhandle) which actually lets you see the filepath to which the handle is referring. But still no way to modify it though...

Mueller answered 25/10, 2012 at 15:53 Comment(3)
FWIW, the feval command, which is the most natural place for this capability, specifically excludes specifying the directory. "The fname parameter must be a simple function name; it cannot contain path information."Seigneury
Just as a general interest: do you remember why you didn't want to put the directory on your path?Conjugate
@RodyOldenhuis At the company I work, we work with several users on the same server with RDP with one matlab instal (thus one matlabrc, one path, etc.) Users are generally not careful with the path and butcher it constantly. Many users name their functions incorrectly and shadow sometimes even core matlab functions, then add their folder to the path. I see code everywhere with removepath(...);function();addpath(...) and the like... This breaks if 2 users do it at the same time. So the easiest solution would be to be able to call a specific function directly without worrying about the pathMueller
U
6

The solution as noted in the comment 1 to create a function handle before calling the function is nicely implemented by @Rody Oldenhuis' FEX Contribution: http://www.mathworks.com/matlabcentral/fileexchange/45941-constructor-for-functionhandles

Unaccustomed answered 20/3, 2014 at 12:23 Comment(1)
Uses cd the same way as all the other implementations?Wearproof
L
10

This is doable, but requires a bit of parsing, and a call to evalin.

I added (many years ago!) a function to the MATLAB Central File Exchange called externalFcn

http://www.mathworks.com/matlabcentral/fileexchange/4361-externalfcn

that manages calls to off-path functions. For instance, I have a function called offpathFcn that simply returns a structure with a success message, and the value of an input. Storing that function off my MATLAB path, I can call it using:

externalfcn('out = C:\MFILES_OffPath\offpathFcn(''this is a test'')');

This returns:

out = 
    success: 1
    input: 'this is a test'

(Note that my implementation is limited, and improvable; you have to include an output with an equal sign for this to work. But it should show you how to achieve what you want.)

(MathWorks application engineer)

Logographic answered 25/10, 2012 at 16:26 Comment(4)
Thanks for your reply. Yes I found externalfcn while searching for a solution, but this indeed cds to the directory and cds back. This is unacceptably slow for my purposes. The only solution I have found now is to create a handle by cding and cding back... Once you have the handle, function calls are quick.Mueller
@reverse_engineer: If you came up with an improved method like handles, could you please post it as an answer? You will have my +1.Congruity
@Congruity No, the solution I used in the end was to cd to the directory, create a handle there, and cd-ing back. Then the handle still refers to the function in the specific folder that is not on the path, and you can call this handle. But I've found no way to call a function not on the path with any other method...Mueller
I followed your link and it's dated January 2004, that's not many years ago after all ;) Happy 10th birthday (with a little offset of 7 months... not that much either :P)Trove
U
6

The solution as noted in the comment 1 to create a function handle before calling the function is nicely implemented by @Rody Oldenhuis' FEX Contribution: http://www.mathworks.com/matlabcentral/fileexchange/45941-constructor-for-functionhandles

Unaccustomed answered 20/3, 2014 at 12:23 Comment(1)
Uses cd the same way as all the other implementations?Wearproof
U
4
function [varargout]=funeval(fun,varargin)
% INPUT:
% fun: (char) full path to function file
curdir=cd;
[fundir,funname]=fileparts(fun);
cd(fundir);
[varargout{1:nargout}] =feval(funname,varargin{:})
cd(curdir);
Unaccustomed answered 3/6, 2013 at 18:29 Comment(3)
Could you provide some explanation?Chosen
Thanks for your answer, but this implies cd-ing to the function directory, which I would have liked to avoid...Mueller
I don't know any other way: Matlab needs to know the function you mean. For it, as far as I know there are only two possibilities: either it is in the Matlab path or the current directory.Unaccustomed
T
3

I've modified Thierry Dalon's code to avoid the use of feval, which I always feel uncomfortable with. Note this still doesn't get around cd-ing to the directory in question, but well, it happens behind the scenes, so pretend it doesn't happen :-) Also note what Ben Voigt pointed out above: calls to helper functions off the path will fail.

function [varargout]=funeval(FunctionHandle, FunctionPath, varargin)
% INPUT:
% FunctionHandle: handle to the function to be called; eg @MyFunction
% FunctionPath: the path to that function
% varargin: the arguments to be passed to Myfunction
curdir=cd;
cd(FunctionPath)
[varargout{1:nargout}] = FunctionHandle(varargin{:});
cd(curdir);
end

and calling it would look like

Output = funeval(@MyFunction, 'c:\SomeDirOffMatlabsPath\', InputArgToMyFunc)
Tallowy answered 7/11, 2013 at 15:39 Comment(1)
in what way is this answer different than Dalon`s one? don't dup answers...Firstfoot
S
2

The run command can run a script file from any directory, but it can't call a function (with input and output arguments).

Neither feval nor str2func permit directory information in the function string.

I suggest writing your own wrapper for str2func that:

  • saves the working directory
  • changes directory to the script directory
  • creates a function handle
  • restores the original working directory

Beware, however, that a handle to a function not in the path is likely to break, because the function will be unable to invoke any helper code stored in other files in its directory.

Seigneury answered 25/10, 2012 at 16:20 Comment(1)
Thanks for your reply. I know the command run already and indeed it's something like that I need, but for functions instead of scripts. I called matlab technical help and there is no such built-in solution.Mueller

© 2022 - 2024 — McMap. All rights reserved.