5

If I have a file that's meant to be required by other files, is it possible to get the absolute filepath of the file that's requiring it?

So if lib_file.cr has a macro that is meant to be called by the app_file.cr that imported it, can that macro discover the filepath to app_file.cr at compile time?

I tried stuff like this:

macro tester
  puts __DIR__
  puts __FILE__
end

But when invoked from the file doing the requiring, it gives nothing at compile time and this at runtime:

?
expanded macro: app_file

If I change the macro to this:

macro tester
  {{puts __DIR__}}
  {{puts __FILE__}}
end

It gives me this at compile time:

"/home/user/Documents/crystal_test/lib_file"
"/home/user/Documents/crystal_test/lib_file.cr"

So is there a trick to get the full path to app_file.cr inside lib_file.cr at compile time?

Lye Fish
  • 2,538
  • 15
  • 25
  • 1
    I also tried putting `puts __FILE__` in a separate file and using `{{run(...).stringify}}`, but that gives me the path to that separate file. – Lye Fish Jul 06 '15 at 00:47

1 Answers1

7

You can use default args with __FILE__ to get the file that is calling the macro.

macro tester(file = __FILE__)
  {{puts file}} # Print at compile time
  puts {{file}} # Print at runtime
end
Jonne Haß
  • 4,792
  • 18
  • 30
Brian J Cardiff
  • 629
  • 4
  • 7
  • 1
    you have also `__LINE__` so you can get where the macro was called from. I used at https://gist.github.com/bcardiff/740e8c1f7c7fbc456bb0 . Yet there is way AFAIK to know the file that is requiring the lib without using a macro, which was your original question. – Brian J Cardiff Jul 06 '15 at 01:24
  • 1
    Thanks, it looks promising, but it's giving me `undefined local variable or method 'file'`. I'll investigate further. – Lye Fish Jul 06 '15 at 02:46
  • 1
    ...ah yes, it needs `{{puts file}}`. Seems to work perfectly. Thank you! – Lye Fish Jul 06 '15 at 02:50