John
John

Reputation: 10079

Examine method metadata (i.e. arity, arg types, etc)

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

Answers (2)

John
John

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

Johannes M&#252;ller
Johannes M&#252;ller

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

Related Questions