跳至内容

宏方法

宏 def 允许您为类层次结构定义一个方法,然后为每个具体的子类型实例化该方法。

如果一个 def 包含一个引用 @type 的宏表达式,则该 def 被隐式地视为 macro def。例如

class Object
  def instance_vars_names
    {{ @type.instance_vars.map &.name.stringify }}
  end
end

class Person
  def initialize(@name : String, @age : Int32)
  end
end

person = Person.new "John", 30
person.instance_vars_names # => ["name", "age"]

在宏定义中,参数以它们的 AST 节点形式传递,允许您在宏展开({{some_macro_argument}})中访问它们。但是,对于宏 def 来说并非如此。这里,参数列表是宏 def 生成的那个方法的参数列表。您无法在编译时访问调用参数。

class Object
  def has_instance_var?(name) : Bool
    # We cannot access name inside the macro expansion here,
    # instead we need to use the macro language to construct an array
    # and do the inclusion check at runtime.
    {{ @type.instance_vars.map &.name.stringify }}.includes? name
  end
end

person = Person.new "John", 30
person.has_instance_var?("name")     # => true
person.has_instance_var?("birthday") # => false