Ferrari177
Ferrari177

Reputation: 31

Haxe Reference Object via String

In Haxe, I am trying to access an object's value via a variable. In JavaScript you use [ ] to access it, but in Haxe this doesn't work and comes back with an error:

String should be Int

Array access is not allowed on { x : Int, name : String }

I need help with the last line of code:

var room = { x: 10, name: 'test' };

trace(room.name);   // this works returns 'test' 

// how do I reference foo to return 'test' as the above result.
var foo = "name";
var results = room[foo];   // need fixing

Upvotes: 3

Views: 638

Answers (3)

Gama11
Gama11

Reputation: 34138

What you're trying to do is called Reflection, and the way to do that in Haxe is via the Reflect API:

var results = Reflect.field(room, "name");

If you want to access a static field instead, pass the Class<T> as the first argument instead of an instance:

class Foo {
    public static var bar = 0;
}

var bar = Reflect.field(Foo, "bar");

For properties with a getter, you'll want to use getProperty() instead.


Note: Reflection is generally considered bad practice as it moves errors from compile- to runtime and is inherently type-unsafe. There are usually better ways to solve a problem, but it's hard to recommend a concrete solution here without more context.

Upvotes: 7

Jonas Malaco
Jonas Malaco

Reputation: 1557

You could alternatively use haxe.DynamicAccess. This is particularly useful if your object is the result of haxe.Json.parse, or by other means a Dynamic.

However, since your example (indirectly) types room, some conversion is needed and you'll still loose typing (you'll have "values" with different types and will need to settle on <Dynamic>):

    var foo = "name";
    var access = (cast room:haxe.DynamicAccess<Dynamic>);
    trace(access[foo]);

(full example)

If your use case has a typed structure that can be converted into a String -> T map or if you're already dealing with dynamics, this is a good fit; otherwise, Reflect or untyped are simpler and therefore better.

Upvotes: 1

user2630051
user2630051

Reputation: 119

You can also use the untyped. eg:

var results = untyped room[foo];

You just need to be careful when using untyped, as it can lead to runtime errors if you don't put appropriate runtime checks in place.

Upvotes: -1

Related Questions