Nested enums and/or classes

I’m trying to translate the following nested structure of Strings (and potentially Ints) into type-safe code that can also be easily type-hinted and refactored via an IDE (so this rules out anonymous structures) , but in the same time must be interpretable at run-time without reflection (which would incur a performance hit upon heavy use, and I do intend some very heavy use of the data below).

In C# or Java I could easily achieve this using nested classes.

My purpose is to allow somebody to drill down through an ever-more-specific categorized hierarchy. The values in the hierarchy must be printable on the screen (without using reflection or “switch” statements), so of course I was thinking about String variables.

Material: "Material"
- Scratched: "Scratched"
--- Damaged: "Damaged"
- Shiny: "Shiny"
--- Polished: "Polished"
----- Reflective: "Reflective"
--- Finished: "Finished"

It could work with enums I guess if only they would allow members to be String values. They could, if I use Switch, but I want to print enum members without resorting to Switch statements.

I also tried @:enum abstract, but I’m kinda stuck with compile errors. For example I tried:

@:enum
abstract Materials (String)
{
	public var name: String = "Materials";
	public var ShinyChild: Shiny;
	public var Scratched: String = "Scratched";
}

@enum
abstract Shiny (String)
{
	var name: String = "Shiny";
	var Polished: String = "Polished";
	var Finished: String = "Finished";
}

I also tried static classes.

class Materials
{
	public static var name: String = "Materials";
	public static var ShinyChild: Shiny;
	public static var Scratched: String = "Scratched";
}

class Shiny
{
	public static var name: String = "Shiny";
	public static var Polished: String = "Polished";
	public static var Finished: String = "Finished";
}

This of course doesn’t work because in Materials.ShinyChild.name ShinyChild is instantiated.

I can do this if I instantiate the hierarchy parent class once. That’s not exactly ideal.

class Materials
{
	public var name: String = "Materials";
	public var child: Shiny = new Shiny();
	public var Scratched: String = "Scratched";
	public function new () {}
}

class Shiny
{
	public var name: String = "Shiny";
	public var Polished: String = "Polished";
	public var Finished: String = "Finished";
	public function new () {}
}
var mat: Materials = new Materials();
w(mat.child.Polished); //Prints "Polished" as desired.

I tried singleton, doesn’t work yet.

Ok, I managed to create this Frankenstein so you can all have a laugh.

class CollectionBase
{
	public var name: String = "None";

	public function new (v: String)
	{ if (v != null) name = v; }

	public function toString(): String	{ return name; }
}

class Materials extends CollectionBase
{
	public var ShinyC: Shiny = new Shiny("Shiny");
	public var Scratched: CollectionBase = new CollectionBase("Scratched");

	public static var instance(default, null):Materials = new Materials("Materials");
	private function new (v: String) { super(v); }
}

class Shiny extends CollectionBase
{
	public var PolishedC: Polished = new Polished("Polished");
	public var Finished: CollectionBase = new CollectionBase("Finished");

	public function new (v: String)	{ super(v); }
}

class Polished extends CollectionBase
{
	public var Reflective: CollectionBase = new CollectionBase("Reflective");

	public function new (v: String)	{ super(v); }
}

This achieves the goal and also encapsulates a collection inside a singleton.

This looks a bit like an XY problem to me as I am not sure what’s the actual intent here. Really just a set of string values grouped in a hierarchy? And if so, why not anonymous structures? Their performance depend on a target, but if you use JS it will be as fast as any other object. And you can give them names using a typedef for easy type hinting and navigation. Otherwise, your solution with class instances isn’t that bad too :slight_smile:

1 Like

It’s not XY problem, it’s just perhaps so ridiculously simple that I overlooked it. I’ve also taken quite a long break from serious coding in the past years so please forgive my silliness :).

typedef? Hm. I didn’t check it out, but my goal is also to allow easy renaming of values throughout the project using refactor. And I need type-safety because if somebody messes with the structure the project needs to fail compiling.

I’m gonna check typedef in more depth tomorrow. I would indeed like an anonymous structure, as long as it satisfies the above requirements. Not familiar with how typedef works in Haxe but what I’ve read now is reassuring.

With anonymous structure it would look like:

If you want the typing for that, just use $type(data), then you can use this as typedef:


As alternative, If you would use enums then the structure could look like this:

But it depends on use case if its useful or not. It can be nice if the structure is more complex and you want to use pattern matching.

1 Like

Aaah, so THAT’s how nested typedefs can be created :smiley:. I was just now following up on @nadako’s comment trying to figure out how to setup a nested typdef. Nice! Thank you guys! :slight_smile:

Well you can do it by hand of course, but doing so basically you let the compiler figure out, and use that :stuck_out_tongue:

1 Like

typedef merely means alias. It is not the name of the type you guys are mentioning. A more correct name would be anonymous structure.

1 Like