从包含的文件中,如何获取包含文件的文件名?

seb*_*seb 9 ruby

为措辞不佳的问题标题道歉 - 不知道如何把它变得更好!

在下面的代码中,当我执行时ruby bar.rb,如何才能使其输出bar.rb,而不是foo.rb

foo.rb:

module Foo
  def filename
    __FILE__
  end
end
Run Code Online (Sandbox Code Playgroud)

bar.rb:

require_relative 'foo'
include Foo

puts filename # outputs 'foo.rb'
Run Code Online (Sandbox Code Playgroud)

这是一个库函数,每次执行一些代码时,都会记录该代码的位置(和git ref).

Ale*_*x D 4

你的问题促使我打开 Ruby 解释器源代码,看看__FILE__实际是如何工作的。答案非常有趣:它是在解析器内部实现的。词法分析器有一个特殊的标记类型__FILE__。当解析器看到该标记时,会将其转换为字符串常量,其中包含解析器正在处理的文件的名称。

来自 ext/ripper/ripper.c 的第 14948 行:

case keyword__FILE__:
return NEW_STR(rb_external_str_new_with_enc(ruby_sourcefile, strlen(ruby_sourcefile),
                        rb_filesystem_encoding()));
Run Code Online (Sandbox Code Playgroud)

我认为这应该清楚地表明,尝试返回__FILE__包含文件的名称是完全不可能的,除非您破解 Ruby 解释器源代码,或者编写自己的预处理器,__FILE__在将 Ruby 源代码传递给解释器之前将其转换为其他内容!