Isn't it dangerous to allow Comma-Separated-List functionality in indexed assignments?
5 次查看(过去 30 天)
显示 更早的评论
I have a function below called renamefields() which, as the name suggests, renames a desired subset of struct array fields as desired. It works now, as the following simple example shows,
[S(1:2).a]=deal(10,20);
T=renamefields(S,'a','b');
[S.a]
[T.b]
Prior to getting it working, though, I had a bug in the code that I've also included below as renamefieldsBUG(). Repeating the steps above, you can see the effect:
T=renamefieldsBUG(S,'a','b');
[T.b]
I know why this occurs. It is because in the buggy version, the right hand side of the assignment S.(srcfields{j}) is a comma-separated list. When the left hand side of a comma-separated list assignment has only a single variable, all but the first element of the list is discarded (see doc). Is this not dangerous behavior, however? It seems like if you wanted this behavior, it should be done with an explicit command. Otherwise, as the example shows, code can be bug-prone.
function S=renamefields(S,srcfields,destfields)
%Rename fields
%
%S=renamefield(S,srcfields,destfields)
N=numel(S);
if ischar(srcfields), srcfields={srcfields}; end
if ischar(destfields), destfields={destfields}; end
M=numel(srcfields);
assert(M==numel(destfields),'src and dest length don''t agree.')
for i=1:N
for j=1:M
S(i).(destfields{j})=S(i).(srcfields{j});
end
end
S=rmfield(S,srcfields);
end
function S=renamefieldsBUG(S,srcfields,destfields)
%Rename fields
%
%S=renamefield(S,srcfields,destfields)
N=numel(S);
if ischar(srcfields), srcfields={srcfields}; end
if ischar(destfields), destfields={destfields}; end
M=numel(srcfields);
assert(M==numel(destfields),'src and dest length don''t agree.')
for i=1:N
for j=1:M
S(i).(destfields{j})=S.(srcfields{j}); %<----BUG: should be S(i) on right side
end
end
S=rmfield(S,srcfields);
end
2 个评论
Paul
2023-2-2
Isn't this behavior needed when calling a function with fewer output arguments than the function actually returns? That is, I thought a function returns a CSL, the elements of which are paired up with the outputs on the calling side.
a = test
Hmm, now that I've typed that, I'm not so sure that a CSL is the actual mechanism for return arguments.
function [a,b] = test
a = 1;
b = 2;
end
回答(1 个)
Walter Roberson
2023-2-2
Consider
x = rand(1,10);
y = power(max(x),2) %also known as y = max(x).^2
How many outputs does max(x) potentially have? Two. Should we require an explicit syntax for discarding all outputs other than the first? It could not be
y = power(discard_trailing_output(max(x)), 2)
-- not without a very serious backwards incompatibility.
Effectively, every function that potentially has more than one output, returns a comma separated list. A function that really cares can detect the situation by examining nargout and chosing not to assign to variables named in the corresponding output positions, or by choosing to assign only to as much of varargout as nargout says is used. But a relatively small fraction of functions do that; most return multiple variables effectively as CSL and MATLAB discards the extras.
2 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!