如何确定函数是否被调用后跟分号(&#34 ;;")?

时间:2014-11-20 20:32:47

标签: matlab function expression

在Matlab脚本中,我调用用户定义的函数(m函数)。我的函数在使用disp和/或fprintf调用将值打印到命令窗口时返回一个值。

在编写表达式或语句时,将;放在其末尾以禁止打印。当表达式调用我的函数时,;可以禁止打印返回的值。但是,这不会影响调用函数中的disp输出。

我想在适当的时候消除该功能的显示输出。 有没有办法确定是否在以; 结尾的表达式中进行了函数调用?

5 个答案:

答案 0 :(得分:3)

我喜欢你想要做的精神,但我认为它可能违背了Matlab中常见的编程模式。正如您所说,终止分号的目的是抑制返回值的打印。试图让它融入你的其他功能可能需要一些深度黑客和丑陋的难以维护的代码。实现所描述内容的标准方法是通过属性名称 - 值对参数。例如,Matlab的优化套件有一个名为'Display'的属性,可以将其设置为各种值,以指示所需的详细程度(参见optimset)。

如果您想尝试查找终止分号的方法,可以查看未记录的mintmlintmexmtree函数 - read more here。不幸的是,使用mlint只是检查“带分号以抑制输出的终止语句”警告(see this function on the MatlabCental File Exchange)在所有情况下都不起作用,因为函数调用本身不会产生此警告。

<强>更新

这是对可以插入到被调用函数中的代码的尝试,以确定调用者的行是否以分号结束。您应该知道,这尚未经过彻底测试,可能非常脆弱。我没有使用子函数或匿名函数对它进行测试,我知道如果使用...在多行上换行,则会失败。

st = dbstack('-completenames');  % M-file of caller and line number
caller = st(2);
str = mlint('-lex',caller.file); % Struct containing parsed data

isSemicolon = false; % Assume no semicolon
for i = 1:length(str)
    % Find end-of-line corresponding to function call
    c = strsplit(str(i).message,'/');
    if str2double(c{1}) == caller.line && strcmp(c{2}(end-5:end-1),'<EOL>')
        % Check for comments
        j = i-1;
        if ~isempty(strfind(str(j).message,'%'))
            j = j-1;
        end
        % Check for semicolon
        if strcmp(str(j).message(end-2),';')
            isSemicolon = true; % Semicolon found
            break;
        end
    end
end

换句话说,玩这个来学习,但我不建议实际使用它。

答案 1 :(得分:1)

我担心你问题的答案是。该信息根本不会传递给被调用的函数。

你不应该考虑添加分号作为“抑制打印”的方法,而是缺少分号指示MATLAB在函数调用的输出变量上调用display函数。换句话说,MATLAB解释了这段代码:

y = myFunc(x)

为:

y = myFunc(x);
display(y);

我认为在您的功能中添加'print'或'verbose'参数是您实现目标的最佳选择。

答案 2 :(得分:1)

我认为实现所需结果的最简单方法(即是否disp显示)是添加额外的功能输入或输出。例如,添加输入(可选,您可以设置默认行为):

function y=myFunc(a,displayResults)
if nargin==1
    displayResults=true; %// set the default behaviour
end

%// if you want to print something
if displayResults
    disp(a)
end
end

或额外的输出。在这种情况下,foo不会向屏幕输出任何内容,但所有消息都会保存到单元格数组中,如果需要可以访问它:

function [x,m] = foo(a)
m={}; %// initialise cell array of output messages

x=a;

m{length(m)+1}=a; %// some message
m{length(m)+1}='another message'; %// another message
end

我认为第一个选项会更好,第二个选项不会很好地处理fprintf,显示m的元素可能会很棘手,具体取决于它包含的内容。第一种方法非常简单,甚至不需要您更改现有代码,因为您可以将displayResults输入设置为可选,并将默认设置为您想要的。

答案 3 :(得分:0)

这是一个可能的解决方法(要清楚 - 这不是问题本身的真正答案,只是一种避免不必要行为的方法)。说我的功能是:

function y = prt_test(x)
    y = x + 1;
    disp('IN PRT_TEST')
end

通话:

>> % Regular use - message and output are displayed:
>> y = prt_test(1)
IN PRT_TEST
y =
     2

>> % Regular use w/ ";" - only message is displayed:
>> y = prt_test(2);
IN PRT_TEST

>> % Use "evalc()" - message and output are displayed:
>> evalc('y = prt_test(3)')
ans =
IN PRT_TEST
y =
     4

>> % Use "evalc()" w/ func ";" - only message is displayed:
>> evalc('y = prt_test(4);')
ans =
IN PRT_TEST

>> % Use "evalc();" - no output:
>> evalc('y = prt_test(5)');

>> % Use "evalc();" w/ func ";" - no output:
>> evalc('y = prt_test(6);');

>>

答案 4 :(得分:0)

您可以通过在函数开头的本地重新定义来抑制disp输出:

function [] = hideDisplay()
%[
    % Override `disp` behavior
    disp = @(x)doNothing;

    % Next `disp` calls will no longer appear in matlab console
    disp('Hello')
    disp('World!')
%]
end

%% ---
function [] = doNothing()
%[
%]
end