changeset 15615:808e4f13e220

doc: Update struct documentation to match new indexing rules * container.txi: Mention that fields can now be arbitrary strings and issues that this may cause with Matlab. * setfield.m: Completely rewrite docstring. More examples. * getfield.m: Remove most of the docstring and refer to setfield's docstring instead.
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Tue, 20 Nov 2012 16:17:01 -0500
parents f2b8f90052fd
children 81db2aca1a84
files doc/interpreter/container.txi scripts/miscellaneous/getfield.m scripts/miscellaneous/setfield.m
diffstat 3 files changed, 96 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/container.txi	Tue Nov 20 13:24:51 2012 -0500
+++ b/doc/interpreter/container.txi	Tue Nov 20 16:17:01 2012 -0500
@@ -38,9 +38,9 @@
 @cindex structures
 @cindex data structures
 
-Octave includes support for organizing data in structures.  The current
+Octave includes support for organizing data in structures. The current
 implementation uses an associative array with indices limited to
-strings, but the syntax is more like C-style structures.  
+strings, but the syntax is more like C-style structures.
 
 @menu
 * Basic Usage and Examples::
@@ -390,6 +390,28 @@
 @end group
 @end example
 
+@noindent
+Dynamic indexing also allows you to use arbitrary strings, not merely
+valid Octave identifiers (note that this does not work on @sc{Matlab}):
+
+@example
+@group
+a = "long field with spaces (and funny char$)";
+x.a = 1;
+x.(a) = 2;
+x
+     @result{} x =
+        @{
+          a =  1
+          long field with spaces (and funny char$) =  2
+        @}
+@end group
+@end example
+
+@noindent
+The warning id @code{Octave:matlab-incompatible} can be enabled to warn
+about this usage. @xref{doc-warning_ids}.
+
 More realistically, all of the functions that operate on strings can be used
 to build the correct field name before it is entered into the data structure.
 
@@ -471,7 +493,7 @@
           field2 =  2
         @}
 @end group
- @end example       
+@end example
 
 @DOCSTRING(struct)
 
@@ -491,9 +513,9 @@
 
 @DOCSTRING(isfield)
 
-@DOCSTRING(getfield)
+@DOCSTRING(setfield)
 
-@DOCSTRING(setfield)
+@DOCSTRING(getfield)
 
 @DOCSTRING(rmfield)
 
--- a/scripts/miscellaneous/getfield.m	Tue Nov 20 13:24:51 2012 -0500
+++ b/scripts/miscellaneous/getfield.m	Tue Nov 20 16:17:01 2012 -0500
@@ -18,28 +18,12 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {[@var{v1}, @dots{}] =} getfield (@var{s}, @var{key}, @dots{})
-## Extract a field from a structure (or a nested structure).  For example:
-##
-## @example
-## @group
-## ss(1,2).fd(3).b = 5;
-## getfield (ss, @{1,2@}, "fd", @{3@}, "b")
-##    @result{} 5
-## @end group
-## @end example
+## @deftypefn {Function File} {[@var{val}] =} getfield (@var{s}, @var{field})
+## @deftypefnx {Function File} {[@var{val}] =} getfield (@var{s}, @var{idx1}, @var{field1}, @var{idx2}, @var{field2}, @dots{})
+## Extract a field from a structure (or a nested structure). The syntax
+## is the same as @code{setfield}, except it omits the final @var{val}
+## argument, returning this value instead of setting it.
 ##
-## Note that the function call in the previous example is equivalent to
-## the expression
-##
-## @example
-## @group
-## i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4= "b";
-## ss(i1@{:@}).(i2)(i3@{:@}).(i4)
-##    @result{} 5
-##
-## @end group
-## @end example
 ## @seealso{setfield, rmfield, isfield, isstruct, fieldnames, struct}
 ## @end deftypefn
 
--- a/scripts/miscellaneous/setfield.m	Tue Nov 20 13:24:51 2012 -0500
+++ b/scripts/miscellaneous/setfield.m	Tue Nov 20 16:17:01 2012 -0500
@@ -18,25 +18,80 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {[@var{k1}, @dots{}, @var{v1}] =} setfield (@var{s}, @var{k1}, @var{v1}, @dots{})
-## Set a field member in a (nested) structure array.  For example:
+## @deftypefn {Function File} {@var{s} =} setfield (@var{s}, @var{field}, @var{val})
+## @deftypefnx {Function File} {@var{s} =} setfield (@var{s}, @var{idx1}, @var{field1}, @var{idx2}, @var{field2}, @dots{}, @var{val})
+##
+## Set a field member @var{field} in a structure @var{s} equal to @var{val}.  For example:
 ##
 ## @example
 ## @group
-## oo(1,1).f0 = 1;
-## oo = setfield (oo, @{1,2@}, "fd", @{3@}, "b", 6);
-## oo(1,2).fd(3).b == 6
-##      @result{} ans = 1
+## @var{s} = struct ();
+## @var{s} = setfield (@var{s}, "foo bar", 42);
 ## @end group
 ## @end example
 ##
+## @noindent
+## This is equivalent to
+##
+## @example
+## @var{s}.("foo bar") = 42;
+## @end example
+##
+## @noindent
+## Note that ordinary structure syntax @code{@var{s}.foo bar = 42} cannot be
+## used here, as the field name is not a valid Octave identifier. Using
+## arbitrary strings for field name is incompatible with @sc{Matlab}, so
+## this usage will warn if the @code{Octave:matlab-incompatible} warning
+## is set. @xref{doc-warning_ids}.
+##
+## With the second calling form, set a field on a structure array,
+## possibly nested, with successive nested indices @var{idx1},
+## @var{idx2}, @dots{} and fields @var{field1}, @var{field2}, @dots{}
+## The indices must be cells containing the desired index at this
+## nesting depth.
+##
+## Thus consider instead,
+##
+## @example
+## @group
+## @var{s} = struct ("baz", 42);
+## setfield (@var{s}, @{1@}, "foo", @{1@}, "bar", 5)
+##     @result{} ans =
+##     scalar structure containing the fields:
+##       baz =  42
+##       foo =
+##         scalar structure containing the fields:
+##           bar =  54
+## @end group
+## @end example
+##
+## Here we first have an ordinary structure array with one field
+## @code{baz} set to 42. Then we set another field in a nested scalar structure
+## indexing with two single cells containing the unique desired indices.
+##
+## Finally an example with nested structure arrays,
+##
+## @example
+## @group
+## @var{sa}.foo = 1;
+## @var{sa} = setfield (@var{sa}, @{2@}, "bar", @{3@}, "baz", 6);
+## @var{sa}(2).bar(3)
+##      @result{} ans =
+##      scalar structure containing the fields:
+##        baz =  6
+## @end group
+## @end example
+##
+## Here @var{sa} is a structure array whose field @code{fd} at elements
+## 1 and 2 field is in turn
+## another structure array whose third element is a structure
+##
 ## Note that the same result as in the above example could be achieved by:
 ##
 ## @example
 ## @group
-## i1 = @{1,2@}; i2 = "fd"; i3 = @{3@}; i4 = "b";
-## oo(i1@{:@}).(i2)(i3@{:@}).(i4) == 6
-##      @result{} ans = 1
+## @var{SA}.foo = 1;
+## @var{SA}(2).bar(3).baz = 6
 ## @end group
 ## @end example
 ## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct}