COMMUNITY

Macro for accessing deeply nested properties

Hi all!

I’d like to use a macro, which would allow access deeply nested properties or return default value or raise an exception containing where access has failed.

We implemented similar functionality for Dynamic data structures using reflect, but obviously it lacks static type checking and existence of the fields can’t be checked during compilation time.

My colleague tried to implement this macro and got some basics done, but since we don’t have enough experience with Haxe macro (and probably even full understanding) we are not sure what would be the best approach for this.

Also I may assume that this functionality is already available in some library.

Could anyone suggest how to address this or maybe suggest a library, if this is implemented already?

Big thanks in advance!

Safety library has similar feature: https://github.com/RealyUniqueName/Safety#safe-navigation-operator.
For obj!.field expression it returns obj.field value or null if obj is null.
Here is the code, which transforms obj!.field: https://github.com/RealyUniqueName/Safety/blob/master/src/safety/macro/SafeAst.hx#L192-L198
Maybe that could give you a hint

1 Like

Your library looks like what we need. So I believe we shouldn’t reinvent this, but rather use your code. Because you are surely way way more advanced.

One question, related to this. Let’s say we are accessing some deeply nested field like in the following example and nestedField is null.

var v:String = obj!.field!.nestedField!.value;

Would we be able to see from the exception raised that it was the nestedField belonging to obj.field?

We’d like to see something like “Unable to access value of field.nestedField, because it is null”. If this sort of “context aware” exceptions is not supported in the Safety library, could you suggest a strategy for implementing such behaviour?

There will be no exception, because !. in my lib is like ?. in other languages. Haxe doesn’t have postfix ? operator, so I had to take !.
In your example v will be null if obj!.field!.nestedField is null.

Ah, true. That was a dumb question :slight_smile: because I’m mixing in my ahead a few related features we need. Basically when accessing unavailable deeply nested field we depending of the situation would need to either:

  • get null (!. syntax is very nice)
  • get default value (i saw Safety has .or macro?)
  • throw an exception explaining where the problem occurred (i also saw .sure and that made me extremely excited)

We just need to play around with your library to get real understanding. So thanks a lot and I’ll get back when we know more.

Hi everyone.

I am from Fedor’s team :slight_smile:

I am doing some experiments with nullability and facing some unclear for me behavior.

I have the following lines in my .hxml:

-lib safety
--macro Safety.safeNavigation("project", true)
--macro nullSafety("project", Strict)

And here is my code:

var data: Dynamic = getDynamicData();
var value: Null<String> = data!.a!.b!.c!.d!.f;
value.sure();  // works fine

data!.a!.b!.c!.d!.f.sure(); // compile error. Null safety: Cannot access "sure" of a nullable value.

As far as I understand, in both cases where .sure() is called, the type is Null<T>.
Could you tell me please, why I am facing such error?
Do I understand something wrong or maybe there is a some bug?

Thanks!

It’s because the type of data!.a!.b!.c!.d!.f is Dynamic in which case Haxe compiler does not call Safety.sure(), but assumes that the dynamic value has it’s own field sure and generates a field access on the value instead of a call to the static extension.