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

时间:2012-10-15 11:35:08

标签: ruby

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

在以下代码中,当我执行ruby bar.rb时,如何将其输出bar.rb而不是foo.rb

foo.rb

module Foo
  def filename
    __FILE__
  end
end

bar.rb

require_relative 'foo'
include Foo

puts filename # outputs 'foo.rb'

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

2 个答案:

答案 0 :(得分: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()));

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

答案 1 :(得分:1)

你可以使用一个技巧。如果将块传递给方法,则可以使用块闭包来确定它的来源。类似的东西:

def filename(&blk)
  blk.eval "__FILE__"
end

但同样,这意味着你必须传递一个阻止。

老实说,我想知道你想要完成什么,除了制作一些常见的核心扩展方法之外,这可能是你真正不想做的事情。