[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Proposal for subsref/subsasgn implementation
From: |
John W. Eaton |
Subject: |
Re: Proposal for subsref/subsasgn implementation |
Date: |
Mon, 13 Nov 2006 17:22:45 -0500 |
On 13-Nov-2006, Michael Goffioul wrote:
| Normally, there should also be a substruct function, whose .m
| implementation is quite
| straightforward.
Is the attached version OK?
While writing the tests, I noticed a couple of problems with isequal
and assert, so there is a patch for those too. I'm not sure the
changes I made are the best fix, so if someone else has a better
solution, I'd appreciate a patch.
Thanks,
jwe
## Copyright (C) 2006 John W. Eaton
##
## This file is part of Octave.
##
## Octave is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2, or (at your option)
## any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING. If not, write to the Free
## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301, USA.
## -*- texinfo -*-
## @deftypefn {Function File} {} setfield (@var{type}, @var{subs}, @dots{})
## Create a subscript structure for use with @code{subsref} or
## @code{subsasgn}.
##
## @example
## @group
## @end group
## @end example
## @seealso{subsref, subsasgn}
## @end deftypefn
## Author: jwe
function retval = substruct (varargin)
nargs = nargin;
if (nargs > 1 && mod (nargs, 2) == 0)
narg_pairs = nargs / 2;
typ = cell (narg_pairs, 1);
sub = cell (narg_pairs, 1);
k = 1;
for i = 1:2:nargs
t = varargin{i};
dot = false;
switch (t)
case { "()", "{}" }
case "."
dot = true;
otherwise
error ("substruct: expecting type to be one of \"()\", \"{}\", or
\".\"");
endswitch
s = varargin{i+1};
if (dot)
if (! ischar (s))
error ("substruct: for type == %s, subs must be a character string",
t);
endif
elseif (! (iscell (s) || (ischar (s) && strcmp (s, ":"))))
error ("substruct: for type == %s, subs must be a cell array or \":\"",
t);
endif
typ{k} = t;
sub{k} = s;
k++;
endfor
retval = struct ("type", typ, "subs", sub);
else
print_usage ();
endif
endfunction
%!test
%! x(1,1).type = "()";
%! x(2,1).type = "{}";
%! x(3,1).type = ".";
%! x(1,1).subs = {1,2,3};
%! x(2,1).subs = ":";
%! x(3,1).subs = "foo";
%! y = substruct ("()", {1,2,3}, "{}", ":", ".", "foo");
%! assert(x,y);
%!error assert(substruct);
%!error assert(substruct (1, 2, 3));
%!error assert(substruct ("x", 1));
%!error assert(substruct ("()", [1,2,3]));
%!error assert(substruct (".", {1,2,3}));
scripts/ChangeLog
2006-11-13 John W. Eaton <address@hidden>
* miscellaneous/substruct.m: New function.
* testfun/assert.m: Force orientation to match when comparing
struct elements.
* general/__isequal__.m: Avoid assignment of comma-separated lists
when comparing structs.
Index: scripts/general/__isequal__.m
===================================================================
RCS file: /cvs/octave/scripts/general/__isequal__.m,v
retrieving revision 1.8
diff -u -u -r1.8 __isequal__.m
--- scripts/general/__isequal__.m 1 Nov 2006 16:54:04 -0000 1.8
+++ scripts/general/__isequal__.m 13 Nov 2006 22:19:06 -0000
@@ -104,9 +104,9 @@
while (t && idx < l_fn_x)
## Test that all field values are equal.
idx++;
- args = {nans_compare_equal, x.(fn_x{idx})};
+ args = {nans_compare_equal, {x.(fn_x{idx})}};
for argn = 1:l_v
- args{argn+2} = varargin{argn}.(fn_x{idx});
+ args{argn+2} = {varargin{argn}.(fn_x{idx})};
endfor
## Minimize function calls by calling for all the arguments at
## once.
Index: scripts/testfun/assert.m
===================================================================
RCS file: /cvs/octave/scripts/testfun/assert.m,v
retrieving revision 1.3
diff -u -u -r1.3 assert.m
--- scripts/testfun/assert.m 10 Oct 2006 16:10:31 -0000 1.3
+++ scripts/testfun/assert.m 13 Nov 2006 22:19:06 -0000
@@ -110,10 +110,11 @@
for [v,k] = cond
if !struct_contains(expected,k), error; endif
if empty, v = cell(1,0); endif
- if normal, v = {v}; endif
- assert(v,{expected.(k)},tol);
+ if normal, v = {v}; else v = v(:)'; endif
+ assert(v,{expected.(k)},tol)
endfor
catch
+ "catch"
iserror = 1;
end
endif