Как я могу получить название процедуры в Nim?
Я пытаюсь написать макрос для отладочной печати на языке Nim. В настоящее время этот макрос добавляет filename
а такжеline
на выход instantiationInfo()
,
import macros
macro debugPrint(msg: untyped): typed =
result = quote do:
let pos = instantiationInfo()
echo pos.filename, ":", pos.line, ": ", `msg`
proc hello() =
debugPrint "foo bar"
hello()
в настоящее время вывод:
debug_print.nim:9: foo bar
Я хотел бы добавить имя процедуры (или итератора) места, где был вызван макрос.
желаемый результат:
debug_print.nim:9(proc hello): foo bar
Как я могу получить имя процедуры (или итератор) в Nim, как __func__
в С?
2 ответа
Во время выполнения вы можете сделать getFrame().procname
, но он работает только с включенной функцией трассировки стека (не в выпусках сборки).
На удивление во время компиляции я не могу найти способ сделать это. Есть callsite()
в модуле макросов, но это не достаточно далеко. Это звучит как то, что может вписаться в macros.LineInfo
объект.
Хакерское решение было бы также использовать __func__
и разобрать это обратно в имя процесса Nim:
template procName: string =
var name: cstring
{.emit: "`name` = __func__;".}
($name).rsplit('_', 1)[0]
Опираясь на ответ из @def-, но делая его более устойчивым для обработки крайних случаев функций, содержащих подчеркивания, и хэшей, содержащих конечные _N, или не используя также более уникальные имена, так как в противном случае макрос потерпит неудачу, если proc определит переменную name
import strutils
proc procNameAux*(name:cstring): string =
let temp=($name).rsplit('_', 2)
#CHECKME: IMPROVE; the magic '4' chosen to be enough for most cases
# EG: bar_baz_9c8JPzPvtM9azO6OB23bjc3Q_3
if temp.len>=3 and temp[2].len < 4:
($name).rsplit('_', 2)[0]
else:
# EG: foo_9c8JPzPvtM9azO6OB23bjc3Q
($name).rsplit('_', 1)[0]
template procName*: string =
var name2: cstring
{.emit: "`name2` = __func__;".}
procNameAux(name2)
proc foo_bar()=
echo procName # prints foo_bar
foo_bar()
ПРИМЕЧАНИЕ: это все еще имеет некоторые проблемы, которые запускаются в сложных крайних случаях, см. https://github.com/nim-lang/Nim/issues/8212