[Interest] Will Qt6 end this enum issue? (or even 5.15?)

Max Paperno max-l at wdg.us
Fri Mar 20 14:08:53 CET 2020


And putting my money where my mouth is... This example could probably be 
improved but it covers the basic idea. I looked around for something 
already made, but didn't see a simple version which could handle both 
implicit value assignment (auto-incrementing values) and explicit 
values, never mind a mix of the two. The assignment syntax is not as 
clean as I'd like (with the strings/objects), but it's flexible, so 
whatever.

For use in QML, put this in an external file:

lib.js:
-----------------
function Enum()
{
   this.exists = function(value) {
     return (typeof this[value] !== "undefined");
   };

   let lastValue = 0,
     i;
   for (i in arguments) {
     let arg = arguments[i],
       name, value;

     if (typeof arg === "object") {
       name = Object.keys(arg)[0];
       value = Object.values(arg)[0];
     }
     else if (typeof arg === "string") {
       name = arg;
       value = lastValue;
     }
     else {
       continue;
     }

     if (this.exists(name))
       throw "Duplicate enum name: " + name;

     this[this[name] = value] = name;
     lastValue = value + 1;
   }

   Object.freeze(this);  // don't allow modification
}
-------------------


Test.qml:
------------
import QtQuick 2.9
import "lib.js" as Lib

Item {
   // ... other properties, etc

   readonly property var positions: new Lib.Enum(
     'Unspecified',   // automatic value, = 0
     {BackFace : 5},  // explicit value
     'FrontFace'      // auto next value, = 6
   );

   function test() {
     console.log(positions.BackFace, positions[positions.BackFace]);
     // qml: 5 BackFace

     console.log(positions.FrontFace, positions[positions.FrontFace],
                 positions.exists(positions.FrontFace));
     // qml: 6 FrontFace true

     // can't change the value, though strangely(?) no error/warning
     // even with readonly property
     positions["BackFace"] = 25;
     console.log(positions.BackFace);  // qml: 5

     var face = positions.FrontFace;
     switch(face) {
       case positions.BackFace:
         console.log("The back");
         break;
       case positions.FrontFace:
         console.log("The front");
         break;
       case positions.Unspecified:
         console.log("Not specified");
         break;
     }
     // qml: The front
   }

   Component.onCompleted: test();
}
-------------


JavaScript demo:
https://plnkr.co/edit/p9BM4o2SPtvGB3ZC?open=lib%2Fscript.js&preview
(there's a console view which can be opened on the lower right)

Cheers,
-Max



On 3/20/2020 4:56 AM, Max Paperno wrote:
> 
> On 3/20/2020 4:44 AM, Max Paperno wrote:
>>
>> Obviously one could come up with a little helper function/object which 
>> makes this prettier. And you could make it auto-assign incremental 
>> values if one isn't provided in the "constructor" (like a C enum does)
> 
> Err, sorry, I meant a helper object which also provides reverse mapping 
> from symbol to name.
> 
> Something like
> 
> var Enum;
> (function (Enum) {
>      Enum[Enum["A"] = 0] = "A";
> })(Enum || (Enum = {}));
> 
> var a = Enum.A;
> var nameOfA = Enum[a]; // "A"
> 
> See:
> https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings
> 
> Also their enum type implementation in general seems nice.
> 
> -Max



More information about the Interest mailing list