Изучите метаданные метода (например, arity, типы arg и т. Д.) - PullRequest
0 голосов
/ 05 сентября 2018

В Crystal возможно ли просматривать метаданные о методе типа во время компиляции? Например, чтобы определить количество аргументов, которые принимает метод, каковы ограничения типа для аргументов и т. Д.

Просматривая API, макросы Def и Arg компилятора имеют методы, которые якобы возвращают эту метаинформацию, но я не вижу способа доступа к ним , Я подозреваю, что метаинформация доступна только компилятору.

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Я узнал, как это сделать. Я искал не в том месте API. В Crystal::Macros::TypeNode есть макрос methods, который возвращает массив метода Def (именно так вы можете получить к ним доступ). Похоже, класс TypeNode является точкой входа для множества хороших макросов.

Пример использования

class Person
  def name(a)
    "John"
  end

  def test
    {{@type.methods.map(&.name).join(', ')}}
  end
end

Или

{{@type.methods.first.args.first.name}}

Простой возврат имени аргумента представляет интересную проблему, поскольку после того, как интерпретатор макросов вставит его в программу, компилятор интерпретирует имя как переменную (что имеет смысл).

Но значение real происходит в том случае, если он может видеть ограничения типов аргументов метода

class Public < Person
  def name(a : String)
    a
  end

  def max
    {{@type.methods.first.args.first.restriction}}
  end
end

Person.new.max # => String
0 голосов
/ 05 сентября 2018

Я подозреваю, что метаинформация доступна только компилятору.

Точно. Кристалл не имеет отражения во время выполнения. Вы можете многое сделать с макросами во время компиляции, но после компиляции информация о типах и методах больше не доступна.

Но, поскольку все в программе известно во время компиляции, вам не нужно действительно размышлять во время выполнения.

...