Are there enumerated types in MATLAB? If not, what are the alternatives?
After trying out the other suggestions on this page, I landed on Andrew's fully object-oriented approach. Very nice - thanks Andrew.
In case anyone is interested, however, I made (what I think are) some improvements. In particular, I removed the need to double-specify the name of the enum object. The names are now derived using reflection and the metaclass system. Further, the eq() and ismember() functions were re-written to give back properly-shaped return values for matrices of enum objects. And finally, the check_type_safety() function was modified to make it compatible with package directories (e.g. namespaces).
Seems to work nicely, but let me know what you think:
classdef (Sealed) Color
%COLOR Example of Java-style typesafe enum for Matlab
properties (Constant)
RED = Color(1);
GREEN = Color(2);
BLUE = Color(3);
end
methods (Access = private) % private so that you can''t instatiate directly
function out = Color(InCode)
out.Code = InCode;
end
end
% ============================================================================
% Everything from here down is completely boilerplate - no need to change anything.
% ============================================================================
properties (SetAccess=private) % All these properties are immutable.
Code;
end
properties (Dependent, SetAccess=private)
Name;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
methods
function out = eq(a, b) %EQ Basic "type-safe" eq
check_type_safety(a, b);
out = reshape([a.Code],size(a)) == reshape([b.Code],size(b));
end
function [tf,loc] = ismember(a, b)
check_type_safety(a, b);
[tf,loc] = ismember(reshape([a.Code],size(a)), [b.Code]);
end
function check_type_safety(varargin) %CHECK_TYPE_SAFETY Check that all inputs are of this enum type
theClass = class(varargin{1});
for ii = 2:nargin
if ~isa(varargin{ii}, theClass)
error('Non-typesafe comparison of %s vs. %s', theClass, class(varargin{ii}));
end
end
end
% Display stuff:
function display(obj)
disp([inputname(1) ' =']);
disp(obj);
end
function disp(obj)
if isscalar(obj)
fprintf('%s: %s (%d)\n', class(obj), obj.Name, obj.Code);
else
fprintf('%s array: size %s\n', class(obj), mat2str(size(obj)));
end
end
function name=get.Name(obj)
mc=metaclass(obj);
mp=mc.Properties;
for ii=1:length(mp)
if (mp{ii}.Constant && isequal(obj.(mp{ii}.Name).Code,obj.Code))
name = mp{ii}.Name;
return;
end;
end;
error('Unable to find a %s value of %d',class(obj),obj.Code);
end;
end
end
Thanks, Mason