2016-10-29 62 views
2

在“正常”的代码,可以使用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

您可以使用<进行检查:

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 
+0

谢谢@asterite!我的宏可以以两种方式使用,我重载了定义:https://github.com/citizen428/protocols即使我决定再次删除它,我也学到了很多关于Crystal试图弄清楚的地方。 –

1

cjgajardGitter指出了以下解决方案:

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