嵌套函数在 octave/matlab 中看不到局部变量
Nested function does not see local variable in octave/matlab
我正在尝试在我的八度环境中使用名为 optprop 的 matlab 模块。看来代码有一些兼容性问题。特别是,当我尝试调用
xyz_image = rgb2xyz(rgb_image)
我收到以下错误:
error: 'cwf' undefined near line 1809 column 15
error: called from
astm>getcwf at line 1809 column 4
astm at line 1843 column 5
makecwf>tryastm at line 74 column 5
makecwf at line 59 column 9
wpt at line 33 column 6
i_xyz2xyz at line 28 column 6
i_rgb2xyz at line 54 column 5
optproc at line 315 column 7
rgb2xyz at line 49 column 33
rgb2xyz_norm2 at line 10 column 12
导致错误的代码在astm.m文件中。此文件定义函数:
function z=astm(op,varargin)
persistent cwf lam
%cwf initialization
%nested function
function z=getcwf(name, varargin)
%...
z=cwf; %here cwf is undefined
%...
%actual nested function call
z=getcwf(varargin{:});
%...
在我看来这里一切都很好。嵌套函数应参见 cwf。即使我使用 octave,它也应该支持一切,因为 optprop 包上次更新是在 2007 年。我还尝试了嵌套函数,下面的代码工作得很好:
function nested_function_test()
disp('inside outer function');
local_variable = 'local string content';
function nested_function()
disp('inside nested function');
disp(local_variable);
end
disp('after nested function declaration');
nested_function();
end
我看不出这些代码块有什么区别。为什么 cwf 未定义?
更新:
以防万一。当前对我有用的解决方法:
function z=getcwf(name, varargin)
cwf = varargin{end - 1};
lam = varargin{end};
%...
varargin{end + 1} = cwf;
varargin{end + 1} = lam;
z=getcwf(varargin{:});
这似乎是 Octave 中的一个明确错误。在您的 MWE 中,如果您使 local_variable
持久化,则将重现错误行为。即
function nested_function_test()
disp('inside outer function');
persistent local_variable; % <-- change here, make local_variable persistent
local_variable = 'local string content';
function nested_function()
disp('inside nested function');
disp(local_variable); % <-- local_variable no longer visible
end
disp('after nested function declaration');
nested_function();
end
以上将在 matlab 中运行,但在 Octave 中失败。
特别是,在 matlab 中,在嵌套函数内的调试会话期间,如果您键入 whos
,您将看到两堆变量,一个(空)工作区位于嵌套函数的本地,另一个对应到外部函数,嵌套的内部函数可以访问,包含持久变量。
在 Octave 中,在嵌套函数中键入 whos
只是 returns 一个空的本地工作区,仅此而已。 (如果你删除 persistent
行,你会看到 octave 似乎只是 'import' 将外部局部变量放入本地工作区,而不是同时访问内部和外部,所以看起来 octave对如何创建嵌套函数有不同的方法)。
我鼓励您将此作为正式错误提交到 octave bug tracker1 中。似乎开发人员可能将持久变量视为一种特殊情况,而忘记在他们的嵌套函数的特定实现中考虑这种行为。大概是'import'这一步在特定的地方查看变量,而持久变量存储在别处而遗漏了?
1:啊,看来这个bug已经被报告和确认了,但还没有修复:https://savannah.gnu.org/bugs/index.php?42126
我正在尝试在我的八度环境中使用名为 optprop 的 matlab 模块。看来代码有一些兼容性问题。特别是,当我尝试调用
xyz_image = rgb2xyz(rgb_image)
我收到以下错误:
error: 'cwf' undefined near line 1809 column 15
error: called from
astm>getcwf at line 1809 column 4
astm at line 1843 column 5
makecwf>tryastm at line 74 column 5
makecwf at line 59 column 9
wpt at line 33 column 6
i_xyz2xyz at line 28 column 6
i_rgb2xyz at line 54 column 5
optproc at line 315 column 7
rgb2xyz at line 49 column 33
rgb2xyz_norm2 at line 10 column 12
导致错误的代码在astm.m文件中。此文件定义函数:
function z=astm(op,varargin)
persistent cwf lam
%cwf initialization
%nested function
function z=getcwf(name, varargin)
%...
z=cwf; %here cwf is undefined
%...
%actual nested function call
z=getcwf(varargin{:});
%...
在我看来这里一切都很好。嵌套函数应参见 cwf。即使我使用 octave,它也应该支持一切,因为 optprop 包上次更新是在 2007 年。我还尝试了嵌套函数,下面的代码工作得很好:
function nested_function_test()
disp('inside outer function');
local_variable = 'local string content';
function nested_function()
disp('inside nested function');
disp(local_variable);
end
disp('after nested function declaration');
nested_function();
end
我看不出这些代码块有什么区别。为什么 cwf 未定义?
更新:
以防万一。当前对我有用的解决方法:
function z=getcwf(name, varargin)
cwf = varargin{end - 1};
lam = varargin{end};
%...
varargin{end + 1} = cwf;
varargin{end + 1} = lam;
z=getcwf(varargin{:});
这似乎是 Octave 中的一个明确错误。在您的 MWE 中,如果您使 local_variable
持久化,则将重现错误行为。即
function nested_function_test()
disp('inside outer function');
persistent local_variable; % <-- change here, make local_variable persistent
local_variable = 'local string content';
function nested_function()
disp('inside nested function');
disp(local_variable); % <-- local_variable no longer visible
end
disp('after nested function declaration');
nested_function();
end
以上将在 matlab 中运行,但在 Octave 中失败。
特别是,在 matlab 中,在嵌套函数内的调试会话期间,如果您键入 whos
,您将看到两堆变量,一个(空)工作区位于嵌套函数的本地,另一个对应到外部函数,嵌套的内部函数可以访问,包含持久变量。
在 Octave 中,在嵌套函数中键入 whos
只是 returns 一个空的本地工作区,仅此而已。 (如果你删除 persistent
行,你会看到 octave 似乎只是 'import' 将外部局部变量放入本地工作区,而不是同时访问内部和外部,所以看起来 octave对如何创建嵌套函数有不同的方法)。
我鼓励您将此作为正式错误提交到 octave bug tracker1 中。似乎开发人员可能将持久变量视为一种特殊情况,而忘记在他们的嵌套函数的特定实现中考虑这种行为。大概是'import'这一步在特定的地方查看变量,而持久变量存储在别处而遗漏了?
1:啊,看来这个bug已经被报告和确认了,但还没有修复:https://savannah.gnu.org/bugs/index.php?42126