除了解析函数文件之外,有没有办法在matlab中获得函数的输入和输出参数的名称?
例如,给定以下函数文件:
divide.m
function [value, remain] = divide(left, right)
value = floor(left / right);
remain = left / right - value;
end
在函数外部,我希望获得一个输出参数数组,此处为:['value', 'remain']
,类似地,输入参数为:['left', 'right']
。
在matlab中有没有一种简单的方法可以做到这一点?Matlab通常似乎很好地支持反射。
编辑背景:
这样做的目的是在一个窗口中显示函数参数,以供用户进入。我正在编写一种信号处理程序,对这些信号执行操作的函数存储在一个子文件夹中。我已经有了一个列表和每个函数的名称,用户可以从中选择,但一些函数需要额外的参数(例如,平滑函数可能会将窗口大小作为参数)。
此时,我可以在程序将找到的子文件夹中添加一个新函数,用户可以选择它来执行操作。我缺少的是让用户指定输入和输出参数,在这里我遇到了一个障碍,因为我找不到函数的名称。
发布于 2012-05-25 08:09:54
MATLAB提供了一种获取类元数据信息的方法(使用meta
包),但是这只适用于OOP类,而不适用于常规函数。
一个技巧是动态编写一个类定义,其中包含您想要处理的函数的源代码,并让MATLAB处理源代码的解析(正如您所想象的那样:函数定义行跨越多行,在实际定义之前添加注释,等等)
因此,在您的示例中创建的临时文件将如下所示:
classdef SomeTempClassName
methods
function [value, remain] = divide(left, right)
%# ...
end
end
end
然后可以将其传递到meta.class.fromName
以解析元数据...
以下是这种攻击的快速实现:
function [inputNames,outputNames] = getArgNames(functionFile)
%# get some random file name
fname = tempname;
[~,fname] = fileparts(fname);
%# read input function content as string
str = fileread(which(functionFile));
%# build a class containing that function source, and write it to file
fid = fopen([fname '.m'], 'w');
fprintf(fid, 'classdef %s; methods;\n %s\n end; end', fname, str);
fclose(fid);
%# terminating function definition with an end statement is not
%# always required, but now becomes required with classdef
missingEndErrMsg = 'An END might be missing, possibly matching CLASSDEF.';
c = checkcode([fname '.m']); %# run mlint code analyzer on file
if ismember(missingEndErrMsg,{c.message})
% append "end" keyword to class file
str = fileread([fname '.m']);
fid = fopen([fname '.m'], 'w');
fprintf(fid, '%s \n end', str);
fclose(fid);
end
%# refresh path to force MATLAB to detect new class
rehash
%# introspection (deal with cases of nested/sub-function)
m = meta.class.fromName(fname);
idx = find(ismember({m.MethodList.Name},functionFile));
inputNames = m.MethodList(idx).InputNames;
outputNames = m.MethodList(idx).OutputNames;
%# delete temp file when done
delete([fname '.m'])
end
然后简单地运行如下命令:
>> [in,out] = getArgNames('divide')
in =
'left'
'right'
out =
'value'
'remain'
发布于 2012-05-30 04:14:33
对于一般的函数(想想varargin之类的东西),这将是非常困难的(阅读:不可能)。另外,一般来说,依赖变量名作为文档的一种形式可能是...不是你想要的。我将提出一种不同的方法。
既然您控制了程序,那么如何不仅使用m-file指定每个模块,还使用包含额外信息的表项指定每个模块。你可以记录额外的参数,函数本身,当选项是布尔值时注释,并将它们显示为复选框,等等。
现在,把这个放在哪里?我建议让主m-file函数返回结构,作为一种模块加载步骤,并使用一个函数句柄指向执行实际工作的子函数(或嵌套函数)。这保留了我确信您希望保留的单文件设置,并为您的模块创建了一个更具可配置性的设置。
function module = divide_load()
module.fn = @my_divide;
module.name = 'Divide';
module.description = 'Divide two signals';
module.param(1).name = 'left';
module.param(1).description = 'left signal';
module.param(1).required_shape = 'columnvector';
% Etc, etc.
function [value, remain] = my_divide(left, right)
value = floor(left / right);
remain = left / right - value;
end
end
发布于 2012-05-27 12:37:30
当你不能从编程语言中获得关于其内容的信息(例如,“反射”)时,你必须跳出语言。
另一个帖子建议使用“正则表达式”,当应用于解析实际程序时,它总是失败,因为正则表达式不能解析上下文无关的语言。
为了可靠地做到这一点,您需要一个真正的M语言解析器,它将使您能够访问解析树。那么这就相当简单了。
我们的DMS Software Reengineering Toolkit有一个M语言解析器可用,并且可以做到这一点。
https://stackoverflow.com/questions/10431577
复制相似问题