Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在没有名称空间污染的情况下运行MATLAB代码片段_Matlab_Namespaces_Doctest - Fatal编程技术网

在没有名称空间污染的情况下运行MATLAB代码片段

在没有名称空间污染的情况下运行MATLAB代码片段,matlab,namespaces,doctest,Matlab,Namespaces,Doctest,我正在编写Python的doctesttestrunner的一个版本(部分工作…)。为了实现这一点,我需要在m文件帮助中运行人员示例中的代码。我希望变量从一行转到下一行,例如 % >> I = 5 + 33; % expect no output % >> I % % I = % % 38 % 为了运行测试,我有一个循环,循环匹配搜索测试的正则表达式。对于每个匹配,我evalc示例并确保结果匹配: for I = 1:length(examples)

我正在编写Python的
doctest
testrunner的一个版本(部分工作…)。为了实现这一点,我需要在m文件帮助中运行人员示例中的代码。我希望变量从一行转到下一行,例如

% >> I = 5 + 33; % expect no output
% >> I
% 
% I =
% 
%     38
%
为了运行测试,我有一个循环,循环匹配搜索测试的正则表达式。对于每个匹配,我
evalc
示例并确保结果匹配:

for I = 1:length(examples)
    try
        got = evalc(examples(I).source);
    catch exc
        got = ['??? ' exc.message];
    end

    % process the result...
end
问题在于,示例对
I
的定义现在已经将我循环中的循环变量
删除,因为赋值从
eval
带入了外部范围。我四处寻找能够创建新范围/工作区的东西,但是
evalin
只能重用调用者的工作区,这更糟糕。我也考虑过调用子函数或
保存
/
加载
的选项,但没有得到任何结果,但也许我只是想得不够努力


所以我想我只需要命名我所有的变量
doctest\uuuuu system\uuuu*
,并解决名称空间问题。。。除非您对避免变量名冲突的策略有另一个想法,否则这肯定是一个非常有趣的项目。。我认为最好的选择是编写一个单独的函数来执行测试,并为该函数中的所有变量使用唯一的前缀,以避免名称冲突。以下是我的尝试:

function [PREFIX_b varargout] = testContext(PREFIX_src, PREFIX_srcOutput)
    %# TESTCONTEXT   Executes the source code and tests for
    %#               equality against the expected output
    %#
    %#   Input:
    %#       PREFIX_src       - source to execute, cellarry of statements
    %#       PREFIX_srcOutput - output to expect, cellarray of output of each statement
    %#
    %#   Output:
    %#       PREFIX_b         - true/false for success/failure of test
    %#                          note that the output is strtrim()'ed then strcmp()'ed
    %#       varargout{1}     - variable names assigned in this confined context
    %#       varargout{2}     - variable values assigned
    %#
    %#   Example 1:
    %#       source = { 'I = 5+33;' 'I' };
    %#       output = { [], ['I =' char(10) '    38'] };
    %#       b = testContext(source, output);
    %#
    %#   Example 2:
    %#       source = { 'I = 5+33; J = 2;' 'K = 1;' 'disp(I+J+K)' };
    %#       output = { [], [], '41' };
    %#       [b varNames varValues] = testContext(source, output);
    %#
    %#   See also: eval evalc
    %#

    PREFIX_b = true;

    try
        %# for each statement
        for PREFIX_i=1:numel(PREFIX_src)
            %# evaluate
            PREFIX_output = evalc( PREFIX_src{PREFIX_i} );
            PREFIX_output = strtrim(PREFIX_output);            %# trim whitespaces
            %# compare output
            if ~isempty( PREFIX_srcOutput{PREFIX_i} )
                if ~strcmp(PREFIX_output,PREFIX_srcOutput{PREFIX_i})
                    PREFIX_b = false;
                    return
                end
            end
        end

        if nargout > 1
            %# list created variables in this context
            %#clear ans
            PREFIX_vars = whos('-regexp', '^(?!PREFIX_).*');   %# java regex negative lookahead
            varargout{1} = { PREFIX_vars.name };

            if nargout > 2
                %# return those variables
                varargout{2} = cell(1,numel(PREFIX_vars));
                for PREFIX_i=1:numel(PREFIX_vars)
                    [~,varargout{2}{PREFIX_i}] = evalc( PREFIX_vars(PREFIX_i).name );
                end
            end
        end

    catch ME
        warning(ME.identifier, ME.message)
        PREFIX_b = false;
        varargout{1} = {};
        varargout{2} = {};
    end
end
我假设您能够解析m文件以恢复要测试的示例,其中您有每个语句及其预期输出

作为一个例子,考虑嵌入在函数标题中的这个简单测试:

I = 5 + 33;
J = 2*I;
disp(I+J)
因为只有最后一条语句有输出,所以我们将其测试为:

source = {'I = 5 + 33;' 'J = 2*I;' 'disp(I+J)'};
output = {[], [], '114'};
[b varNames varValues] = testContext(source, output)
结果是:

b =
     1
varNames = 
    'I'    'J'
varValues = 
    [38]    [76]

它显示的测试是否通过或失败。或者,该函数返回在该上下文中创建的变量列表及其值。

Mmm,我刚刚完成了一个稍微不同的版本,但我更喜欢您的版本。我的方法是在每行代码之间进行保存/加载。你的并没有弄乱所有这些,尽管它更为复杂,因为有更多的变量必须有前缀。你介意我把你的功能整合到这个项目中吗?这是一个BSD许可的项目。