1

Is it possible to define multiple enumerations in a single Matlab file? Or is it possible to have "local" enums in the same way we can define local funtions at the end of a file?

I am working on a project where it would be handy to have multiple enumeration classes, but it is annoying to use a classdef every time because it requires a separate file, and this means that there are lots of short files whose sole purpose it is to define enumerations. At the moment, each enumeration looks like this:

classdef exampleEnumType < uint32
    
    enumeration
        zero(0),
        one(1),
        two(2),
    end

end

Is there a way to compactly define enumerations in Matlab so that I do not need a separate file for each (using Matlab 2021a)?

Andrew Janke
  • 23,508
  • 5
  • 56
  • 85
fishlein
  • 145
  • 1
  • 8
  • 1
    What do you need these enigma for? MATLAB doesn’t do type checking, they’re just constants. You can define constants easily, just without them being an enum. – Cris Luengo Sep 06 '21 at 20:07
  • @CrisLuengo Its mainly for scripts which are used by a lot of users that have different possible settings. Storing the settings in an enum makes it easier to understand the code as you read it. – fishlein Sep 07 '21 at 11:30
  • Maybe just some `categorical` variables would be a good approach here? For each different "enumeration" you want, stick a `categorical` array holding all the valid values for it in a `Constant` property all in one class. How exactly are these "enumerations" going to be used? – Andrew Janke Sep 18 '21 at 15:49

3 Answers3

1

First of all, having lots of short files is the normal situation in MATLAB. Working around that is possible but oftentimes futile.

Traditionally in MATLAB, constant values are defined as a function. For example, pi is a function. It looks something like this:

function v = pi
   v = 3.14159

By making the constant into a function, it is available from everywhere without first running code to define those constants.

An enumeration is nothing more than a series of constants. The same can be accomplished with a struct:

exampleEnumType = struct('zero',0, 'one',1, 'two',2);

Since fairly recently (R2019b), MATLAB allows dot indexing into the output of a function call, but you do need to use empty parenthesis in the function call. Thus, we can declare the above struct the same way we did with constants:

function v = exampleEnumType
   v = struct('zero',0, 'one',1, 'two',2);

This allows to do exampleEnumType().zero (almost) like with the enum or with a struct variable.

So how do we extend this to defining multiple of these in a single file? If a common prefix is no problem, we can define a class with static member functions, each one declaring a constant:

classdef constants
   methods(Static)
       function v = pi
          v = 3.14159
       end
       function v = exampleEnumType
          v = struct('zero',0, 'one',1, 'two',2);
       end
   end
end

We now have constants.pi and constants.exampleEnumType().zero.

Alternatively, create a single function that returns a more complex struct as follows:

function v = constants
   v.pi = 3.14159;
   v.exampleEnumType = struct('zero',0, 'one',1, 'two',2);

This allows us to do constants().exampleEnumType.zero.

Note that the above will not work in the same way for MATLAB releases prior to R2019b. For older versions of MATLAB, the last method (a function constants) would be the best approach. The user would just need to do constants = constants; at the top of any function needing to use the constants. This shadows the function with a variable of the same name, so that constants.exampleEnumType.zero works as expected.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • Thanks for your comment and suggestion, one point is that `exampleEnumType.zero` will not work, but you need to call `exampleEnumType().zero` (see https://uk.mathworks.com/help/matlab/matlab_prog/indexing-into-function-call-results.html Supported Syntaxes under the first point) – fishlein Sep 07 '21 at 15:22
  • After a bit more playing around, my point above only applies to standalone functions but not to methods of a class. – fishlein Sep 07 '21 at 15:26
  • @fishlein Interesting, I hadn't noticed that caveat. Will update answer. It is unfortunate, because in general it is not necessary to use empty parenthesis to call a function. – Cris Luengo Sep 07 '21 at 15:28
0

You can use a map...

exampleEnum = containers.Map( {'zero','one','two'}, {0,1,2} );

usage looks like

exampleEnum('zero') % = 0
Wolfie
  • 27,562
  • 7
  • 28
  • 55
0

I'm thinking you might want to use categorical arrays here, and stick "enumerations" of their valid values as constants in a common class.

classdef Constants

    properties (Constant)
        
        Foods = categorical(["apple", "banana", "pear"])

        SupportedProtocols = categorical("http", "https", "ftp")

        SpeedOfGravityMps = 9.86

    end

end

If you want them to be true Matlab enumerations, then yeah, you're stuck with a separate file for each.

Andrew Janke
  • 23,508
  • 5
  • 56
  • 85