以下解决方案源于几个变通方法/黑客,不是标准 MATLAB 的 OO 构造的一部分。谨慎使用。
你需要:
evalin()
进入工作空间,工作空间变量'caller'
的名称和类'base'
- 检索最后执行的命令
- 提取分配变量的名称,例如
regexp()
- 比较名称和类别。如果发生完全匹配,即
'base'
工作区中的变量被同一类的新实例覆盖,请向用户询问input()
. 如果用户选择保留现有对象,则用现有的实例覆盖新实例evalin('caller',...)
。
班级foo
:
classdef foo < handle
properties
check = true;
end
methods
function obj = foo()
% variable names and sizes from base workspace
ws = evalin('base','whos');
% Last executed command from window
fid = fopen([prefdir,'\history.m'],'rt');
while ~feof(fid)
lastline = fgetl(fid);
end
fclose(fid);
% Compare names and classes
outname = regexp(lastline,'\<[a-zA-Z]\w*(?=.*?=)','match','once');
if isempty(outname); outname = 'ans'; end
% Check if variables in the workspace have same name
idx = strcmp({ws.name}, outname);
% Ask questions
if any(idx) && strcmp(ws(idx).class, 'foo')
s = input(sprintf(['''%s'' already exists. '...
'Replace it with default? (y/n): '],outname),'s');
% Overwrite new instance with existing one to preserve it
if strcmpi(s,'n')
obj = evalin('caller',outname);
end
end
end
end
end
课堂活动:
% create class and change a property from default (true) to false
clear b
b = foo
b =
foo with properties:
check: 1
b.check = false
b =
foo with properties:
check: 0
% Avoid overwriting
b = foo
'b' already exists. Replace it with default? (y/n): n
b
b =
foo with properties:
check: 0
缺点(见上文):
- 仅适用于 cmw 行和脚本执行的命令,不适用于函数(请参阅链接以扩展函数调用)。此外,如果阅读history.m出现问题,可能会中断。
- 当前的正则表达式在
a==b
.
- 危险,因为用户输入
evalin()
打开了潜在的安全威胁。即使使用正则表达式和字符串比较过滤输入,如果稍后重新访问代码,该构造也可能会造成问题。