マクロメソッド¶
マクロ `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