Reputation: 10079
In Crystal, is it possible to view metadata on a type's method at compile time? For example, to determine the number of arguments the method accepts, what the type restrictions on the arguments are, etc.
Looking through the API, the compiler's Def
and Arg
macros have methods which supposedly return this meta information, but I can't see a way of accessing them. I suspect the meta information is only accessible by the compiler.
Upvotes: 3
Views: 141
Reputation: 10079
I found out how to do it. I was looking in the wrong place of the API. The Crystal::Macros::TypeNode
has a methods
macro which returns an array of method Def
(which is how you can access them). It looks like the TypeNode
class is the entry point to a lot of good macros.
Usage example
class Person
def name(a)
"John"
end
def test
{{@type.methods.map(&.name).join(', ')}}
end
end
Or
{{@type.methods.first.args.first.name}}
Simply returning the argument name posses an interesting problem, because, after the macro interpreter pastes it into the program, the compiler interprets the name as a variable (which makes sense).
But the real value happens in being able to see the type restrictions of the method arguments
class Public < Person
def name(a : String)
a
end
def max
{{@type.methods.first.args.first.restriction}}
end
end
Person.new.max # => String
Upvotes: 3
Reputation: 5661
I suspect the meta information is only accessible by the compiler.
Exactly. Crystal does not have runtime reflection. You can do a lot with macros at compile time, but once it is compiled, type and method information is no longer available.
But, since everything in a program is known a compile time, you shouldn't really need runtime reflection.
Upvotes: 0