在宏内重新打开类或结构

在"normal"代码中,可以使用 klass.is_a?(Reference.class) 来检查是否使用 classstruct 实现了一个类:

Array.is_a?(Reference.class) #=> true
Tuple.is_a?(Reference.class) #=> false

但是,我似乎无法弄清楚如何在宏中重新打开所述类/结构 .

例如:如果我将 Array 类传递给我的宏,我需要生成以 class Array 开头的代码,而对于 Tuple ,它需要是 struct Tuple .

我一遍又一遍地阅读了docs for Crystal::Macros,但是我无法想出能够满足我需要和编译的代码 .

回答(2)

2 years ago

您可以使用 < 来检查:

class MyClass
end

struct MyStruct
end

p {{ MyClass < Reference }}  # => true
p {{ MyClass < Struct }}     # => false
p {{ MyStruct < Struct }}    # => true
p {{ MyStruct < Reference }} # => false

但是,我建议要求用户在所述类型中使用宏 . 这样您就不需要重新打开类/结构,因为您已经在其中 .

这是标准库和语言中实现的内容 . 例如:

class Foo
  # it's not "include Foo, Bar" where "include" reopens the type
  include Bar 

  # It's not "JSON.mapping Foo, ..." where JSON.mapping reopens the type
  JSON.mapping(...) 
end

2 years ago

cjgajardGitter上指出了以下解决方案:

{% if Reference.all_subclasses.includes?(klass.resolve) %}