Labfans是一个针对大学生、工程师和科研工作者的技术社区。 论坛首页 | 联系我们(Contact Us)
MATLAB爱好者论坛-LabFans.com
返回   MATLAB爱好者论坛-LabFans.com > 其它 > 资料存档
资料存档 资料存档
 
 
主题工具 显示模式
旧 2019-12-10, 20:48   #1
poster
高级会员
 
注册日期: 2019-11-21
帖子: 3,006
声望力: 66
poster 正向着好的方向发展
帖子 运行MATLAB代码片段而无名称空间污染

我正在为MATLAB编写Python版本的doctest测试运行程序(部分有效...)。为此,我需要在他们的m文件帮助中的人们的示例中运行代码。我希望变量从一行转移到下一行,例如

% >> I = 5 + 33; % expect no output % >> I % % I = % % 38 % 为了运行测试,我在搜索测试的REGEX匹配项上有一个循环。对于每个匹配项,我都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只能重用调用方的工作区,这甚至更糟。我也考虑过调用子功能或save / load ,但是没有得到任何解决,但是也许我只是没有足够的努力。

所以我想我只需要命名我所有的变量doctest__system__*并解决命名空间问题...除非您对避免变量名冲突的策略有另一个想法?



回答:

当然,这是一个非常有趣的项目。我认为您最好的选择是编写一个单独的函数来执行测试,并对该函数内部的所有变量使用唯一的前缀以避免名称冲突。这是我的尝试:

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] 它显示测试是否通过失败。 (可选)函数返回在该上下文中创建的变量的列表以及它们的值。



更多&回答...
poster 当前离线   回复时引用此帖
 

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛禁用 表情符号
论坛启用 [IMG] 代码
论坛启用 HTML 代码



所有时间均为北京时间。现在的时间是 01:13


Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.