检查方法元数据(即 arity、arg 类型等)
Examine method metadata (i.e. arity, arg types, etc)
在Crystal中,是否可以在编译时查看类型方法的元数据?比如判断方法接受的参数个数,参数的类型限制是什么等等
查看 API,编译器的 Def
and Arg
宏具有据称 return 此元信息的方法,但我看不到访问它们的方法。我怀疑元信息只能由编译器访问。
I suspect the meta information is only accessible by the compiler.
没错。 Crystal 没有运行时反射。您可以在编译时使用宏做很多事情,但是一旦编译,类型和方法信息将不再可用。
但是,由于程序中的所有内容都是编译时已知的,所以您真的不需要运行时反射。
我知道怎么做了。我在 API 的错误位置查找。 Crystal::Macros::TypeNode
有一个 methods
宏,其中 returns 一个方法数组 Def
(这是您访问它们的方式)。看起来 TypeNode
class 是许多优秀宏的入口点。
使用示例
class Person
def name(a)
"John"
end
def test
{{@type.methods.map(&.name).join(', ')}}
end
end
或
{{@type.methods.first.args.first.name}}
简单地返回参数名称有一个有趣的问题,因为在宏解释器将其粘贴到程序中后,编译器将名称解释为变量(这是有道理的)。
但是真正的值正好在能够看到方法参数的类型限制
class Public < Person
def name(a : String)
a
end
def max
{{@type.methods.first.args.first.restriction}}
end
end
Person.new.max # => String
在Crystal中,是否可以在编译时查看类型方法的元数据?比如判断方法接受的参数个数,参数的类型限制是什么等等
查看 API,编译器的 Def
and Arg
宏具有据称 return 此元信息的方法,但我看不到访问它们的方法。我怀疑元信息只能由编译器访问。
I suspect the meta information is only accessible by the compiler.
没错。 Crystal 没有运行时反射。您可以在编译时使用宏做很多事情,但是一旦编译,类型和方法信息将不再可用。
但是,由于程序中的所有内容都是编译时已知的,所以您真的不需要运行时反射。
我知道怎么做了。我在 API 的错误位置查找。 Crystal::Macros::TypeNode
有一个 methods
宏,其中 returns 一个方法数组 Def
(这是您访问它们的方式)。看起来 TypeNode
class 是许多优秀宏的入口点。
使用示例
class Person
def name(a)
"John"
end
def test
{{@type.methods.map(&.name).join(', ')}}
end
end
或
{{@type.methods.first.args.first.name}}
简单地返回参数名称有一个有趣的问题,因为在宏解释器将其粘贴到程序中后,编译器将名称解释为变量(这是有道理的)。
但是真正的值正好在能够看到方法参数的类型限制
class Public < Person
def name(a : String)
a
end
def max
{{@type.methods.first.args.first.restriction}}
end
end
Person.new.max # => String