comparison scripts/miscellaneous/fieldnames.m @ 28166:fab3eeb1fc7e

fieldnames.m: Return only public properties for classdef objects (bug #58012) * fieldnames.m: Use @var{} around output variable name used in documentation. Add new elesif branch to check if input is a classdef object and call properties() to return list of names. Add BIST test for new behavior.
author Rik <rik@octave.org>
date Sat, 21 Mar 2020 19:30:32 -0700
parents bd51beb6205e
children 47d4a84a5725
comparison
equal deleted inserted replaced
28165:a7ba8d4a1da2 28166:fab3eeb1fc7e
26 ## -*- texinfo -*- 26 ## -*- texinfo -*-
27 ## @deftypefn {} {@var{names} =} fieldnames (@var{struct}) 27 ## @deftypefn {} {@var{names} =} fieldnames (@var{struct})
28 ## @deftypefnx {} {@var{names} =} fieldnames (@var{obj}) 28 ## @deftypefnx {} {@var{names} =} fieldnames (@var{obj})
29 ## @deftypefnx {} {@var{names} =} fieldnames (@var{javaobj}) 29 ## @deftypefnx {} {@var{names} =} fieldnames (@var{javaobj})
30 ## @deftypefnx {} {@var{names} =} fieldnames ("@var{javaclassname}") 30 ## @deftypefnx {} {@var{names} =} fieldnames ("@var{javaclassname}")
31 ## Return a cell array of strings with the names of the fields in the 31 ## Return a cell array of strings with the names of the fields in the specified
32 ## specified input. 32 ## input.
33 ## 33 ##
34 ## When the input is a structure @var{struct}, the names are the elements of 34 ## When the input is a structure @var{struct}, the @var{names} are the elements
35 ## the structure. 35 ## of the structure.
36 ## 36 ##
37 ## When the input is an Octave object @var{obj}, the names are the public 37 ## When the input is an Octave object @var{obj}, the @var{names} are the public
38 ## properties of the object. 38 ## properties of the object.
39 ## 39 ##
40 ## When the input is a Java object @var{javaobj} or a string containing the 40 ## When the input is a Java object @var{javaobj} or a string containing the
41 ## name of a Java class @var{javaclassname}, the names are the public fields 41 ## name of a Java class @var{javaclassname}, the @var{names} are the public
42 ## (data members) of the object or class. 42 ## fields (data members) of the object or class.
43 ## @seealso{numfields, isfield, orderfields, struct, methods} 43 ## @seealso{numfields, isfield, orderfields, struct, properties}
44 ## @end deftypefn 44 ## @end deftypefn
45 45
46 function names = fieldnames (obj) 46 function names = fieldnames (obj)
47 47
48 if (nargin != 1) 48 if (nargin != 1)
49 print_usage (); 49 print_usage ();
50 endif 50 endif
51 51
52 if (isstruct (obj) || isobject (obj)) 52 if (isstruct (obj))
53 ## Call internal C++ function for structs or Octave objects
54 names = __fieldnames__ (obj); 53 names = __fieldnames__ (obj);
54 elseif (isobject (obj))
55 names = properties (obj);
55 elseif (isjava (obj) || ischar (obj)) 56 elseif (isjava (obj) || ischar (obj))
56 ## FIXME: Function prototype that accepts java obj exists, but doesn't 57 ## FIXME: Function prototype that accepts java obj exists, but doesn't
57 ## work if obj is java.lang.String. Convert obj to classname. 58 ## work if obj is java.lang.String. Convert obj to classname.
58 ## FIXME: this is now working for objects whose class is in the dynamic 59 ## FIXME: this is now working for objects whose class is in the dynamic
59 ## classpath but will continue to fail if such classnames are used 60 ## classpath but will continue to fail if such classnames are used
68 endif 69 endif
69 70
70 endfunction 71 endfunction
71 72
72 73
73 ## test preservation of fieldname order 74 ## Test preservation of fieldname order
74 %!test 75 %!test
75 %! x(3).d=1; x(2).a=2; x(1).b=3; x(2).c=3; 76 %! x(3).d=1; x(2).a=2; x(1).b=3; x(2).c=3;
76 %! assert (fieldnames (x), {"d"; "a"; "b"; "c"}); 77 %! assert (fieldnames (x), {"d"; "a"; "b"; "c"});
77 78
78 ## test empty structure 79 ## Test empty structure
79 %!test 80 %!test
80 %! s = struct (); 81 %! s = struct ();
81 %! assert (fieldnames (s), cell (0, 1)); 82 %! assert (fieldnames (s), cell (0, 1));
82 83
83 ## test Java classname by passing classname 84 ## Test classdef object
85 %!test
86 %! m = containers.Map ();
87 %! f = fieldnames (m);
88 %! assert (f, {"Count"; "KeyType"; "ValueType"; "map"; "numeric_keys"});
89
90 ## Test Java classname by passing classname
84 %!testif HAVE_JAVA; usejava ("jvm") 91 %!testif HAVE_JAVA; usejava ("jvm")
85 %! names = fieldnames ("java.lang.Double"); 92 %! names = fieldnames ("java.lang.Double");
86 %! assert (any (strcmp (names, "MAX_VALUE"))); 93 %! assert (any (strcmp (names, "MAX_VALUE")));
87 94
88 ## test Java classname by passing java object 95 ## Test Java classname by passing java object
89 %!testif HAVE_JAVA; usejava ("jvm") 96 %!testif HAVE_JAVA; usejava ("jvm")
90 %! names = fieldnames (javaObject ("java.lang.Double", 10)); 97 %! names = fieldnames (javaObject ("java.lang.Double", 10));
91 %! assert (any (strcmp (names, "MAX_VALUE"))); 98 %! assert (any (strcmp (names, "MAX_VALUE")));
92 %! assert (all (ismember ({"POSITIVE_INFINITY", "NEGATIVE_INFINITY", ... 99 %! assert (all (ismember ({"POSITIVE_INFINITY", "NEGATIVE_INFINITY", ...
93 %! "NaN", "MAX_VALUE", "MIN_NORMAL", "MIN_VALUE", ... 100 %! "NaN", "MAX_VALUE", "MIN_NORMAL", "MIN_VALUE", ...