Mercurial > octave
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", ... |