コンテンツへスキップ

マクロメソッド

マクロ `def` を使用すると、クラス階層に対してメソッドを定義できます。このメソッドは、各具体的なサブタイプに対してインスタンス化されます。

`@type` を参照するマクロ式が含まれている場合、`def` は暗黙的にマクロ `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