functions in different files

조회 수: 30 (최근 30일)
Mads
Mads 2016년 9월 1일
댓글: Mads 2016년 9월 2일
Here is one...
I have a main()-function in main.m, and the file includes a subfunction()-function, like:
function main
b = subfunction(c);
f = external(c);
function b = subfunction(c)
b = c^2;
end
and I have an external()-function in external.m, like
function d = external(e)
d = subfunction(e)*2;
I would like to keep the external()-function in this separate file, but I would like it to be able to use sub-functions in the main file. Now I would have expected, since the main.m is initiated that all subfunctions within it was then "declared" globally, but it turns out that the external function can't call the subfunction, even if it has been called before the external function calls it.
Is there a work-around?
Why? I share the main() with other users, and develop the external() until some point of sharing. Until then I would like to keep it private, but still being able to exploit subfunctions. Alternatively I would need to copy all subfunctions in main() that I need into the external.m or into separate files... But when I share stuff, it is sometimes nice not to send hundreds of files around...

채택된 답변

Mads
Mads 2016년 9월 2일
I found a work-around!!
Might be useful to others.
I give the main script an input variable, say 'Fun'. And, say, if Fun=[] then the main() is run as it would be without this trick. Alternatively if main() is called with Fun='test' then main() bypasses its ordinary job and instead runs an "eval('strings = Fun(varargin)')" you know with the correct setting of this string.
So now I can run my external script even from within the main-file and the external script can call functions written inside the main-file.
Voila!
.m:
function Out = main(Fun,In,varargin)
if isempty(Fun)
%%%%
else
if ~isempty(varargin)
str = 'varargin{1}';
for n = 2:nargin-2
str = [str,',varargin{',num2str(n),'}'];
end
eval(sprintf('Out = %s(%s);',Fun,str))
else
eval(sprintf('Out = %s;',Fun))
end
end
end
function a = test(b)
a = b^2;
end
  댓글 수: 2
Stephen23
Stephen23 2016년 9월 2일
편집: Stephen23 2016년 9월 2일
Note that this is just the main function calling one of the local functions. Any main function can do this, so this the expected behavior.
Rather than using slow awful eval, you should consider simply using str2func, which would make your code much much faster, neater, easier to debug, easier to read, simpler, etc:
function out = mainFun(str,varargin)
fun = str2func(str);
out = fun(varargin{:});
end
function a = localFun(b) %#ok<DEFNU>
a = b^2;
end
and tested:
>> mainFun('localFun',2)
ans =
4
Do you see what I did there? By avoiding the slow, buggy, and unnecessary eval, I wrote faster, neater, simpler code.
If you have MATLAB 2013b or more recent you could return the output of the localfunctions
function hnd = mainFun()
hnd = localfunctions;
end
function a = localFun(b) %#ok<DEFNU>
a = b^2;
end
Both of these are going to be much faster and more reliable than any hack code using eval:
Mads
Mads 2016년 9월 2일
Sure. It was a work around and I didn't know about str2func. It is more elegant. Both ways however solve my problem but I will of course continue with the nicer one.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Adam
Adam 2016년 9월 1일
편집: Adam 2016년 9월 2일
Sub-functions have file scope. If you want functions to be seen publicly they either need to be each in their own file or they need to be public methods on a class.
Calling the main function of a file has no bearing on external functions suddenly being able to access the local functions of that file - they are effectively like private functions of a class that don't suddenly get exposed when you start using the class.
You can make use of package folders to group functions, but they still need to be in their own file. You can also zip up folders to send them, of course, rather than sending a load of .m files as they are.

Steven Lord
Steven Lord 2016년 9월 2일
Consider making the subfunction a private function instead of a subfunction. This will prevent arbitrary functions from calling it while still making it accessible to the functions in the directory containing the private subdirectory.
  댓글 수: 1
Mads
Mads 2016년 9월 2일
Not sure if this would solve my original request of avoiding many directories and files, but can't say I fully understand what you suggest. I'm open to the suggestion though.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Scope Variables and Generate Names에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by