@type.instance_vars in finished macro

I’m struggling to figure out a way to support an annotation based method of defining ORM relationships.

https://play.crystal-lang.org/#/r/66dc

The ideal plan would be for something like that, where an annotation can be applied to a property to define the type, and which PK/FK etc to use. However since a type’s ivars are only currently accessible within a method, there would be no way to override the getter/setter without an explicit macro.

So the question is now; does anyone have other ideas on how to implement this and is it possible to expose the ivars within the finished macro?

There’s no way to traverse a type’s instance vars outside of a method definition. This is a limitation of the language. The problem is that finished runs before the instance variables are computed, mainly because finished can define new instance vars… and then if those instance vars are defined or changed there… it’s a bit confusing.

Actually, the whole finished thing is confusing. These macros, together with annotations, should be revisited some day.

Would a workaround be a new macro hook that runs after everything is defined?

For sure, it would make them quite a bit more powerful if you had access to them outside of a method. Assuming annotations are the way of the future, I would love to have that ability.

Otherwise yea, guess ill just have to go the normal macro route :/

The thing is that if we try to “fix” things with more macro hooks and code, things will become pretty obscure. In fact, right now I dislike how much macros are used. They were supposed to be simple but they are all over the place right now in shards… when maybe things should have been a bit simpler.

2 Likes

I think we were actually fine before we had annotations. For example in the JSON.mapping macro you would specify all instance vars and their attributes. That would generate a constructor, properties, etc. It was super simple, no macro finished involved, just a simple macro taking data and spitting out a method. Maybe we should go back to that…

IMO macros + annotations are a nice combination, much better than abusing constants in macros that is quite common now. However the main limitation for annotations is they are still pretty new and lacking some features that would make them be even more powerful. Such as this, or getting an array of types that have a given annotation on them. But i’m sure good solutions will be figured out at some point :)

2 Likes

Come on, guys, let’s add that Ary emoji

Annotations are great. Despite of I don’t like their syntax that much, the possibilites they bring are marvelous. Mostly because of clean, same-indentation-level composition and ability to iterate all of them in any instance method. As @Blacksmoke16 said, they still lack some features, but it shouldn’t be a reason to remove them.

The main thing i love about them is they provide a common “interface” for third party shards to interact with. I.e. a user could easily use a shard that supports annotation by adding them to their class’s properties or methods; without having to use different macros for each thing. I.e. using the JSON.mapping how could someone use a third party serialization shard easily?