Search code examples
crystal-lang

Get filepath of importing file at compile time


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?


Solution

  • 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