2

在“正常”代码中,可以使用klass.is_a?(Reference.class)来检查一个类是否用classor实现struct

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

但是,我似乎无法弄清楚如何在宏中做同样的事情来重新打开所述类/结构。

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

我一遍又一遍地阅读Crystal::Macros 的文档,但我无法提出可以满足我需要并进行编译的代码。

4

2 回答 2

2

您可以使用<以下方法检查:

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
于 2016-10-29T12:23:21.480 回答
1

Gitter上的cjgajard指出了以下解决方案:

{% if Reference.all_subclasses.includes?(klass.resolve) %}
于 2016-10-29T05:05:09.087 回答