我正在开发一个库,可以访问gem元数据,包括它在文件系统上的位置。我们的想法是让gem作者将它设置为任何脚本的相对路径:
# $root/example.gemspec
Example::Gem.root '.' # => $root/
# $root/lib/example/gem.rb
Example::Gem.root '../..' # => $root/
然后,当前脚本的路径将用于计算绝对路径。我的实施目前如下:
def root(relative_to = nil, file = __FILE__)
unless relative_to.nil?
@root = File.expand_path relative_to, File.dirname(file)
end
@root
end
我认为__FILE__
会返回调用者脚本的路径,但这种假设是错误的。
它在图书馆内部工作,但当我试图将它与我的其他宝石集成时崩溃了;生成的路径始终相对于支持库本身。
如何在不必每次通话时都传递当前__FILE__
的情况下实现此目的?否则,没有太大的价值;写root('../..', __FILE__)
几乎与写一个实际的方法来做同样的事情。
如果可以在不必指定任何的情况下找出路径,那就更好了,但我想不出任何东西。 Rails是如何做到的?
顺便说一句,我知道Gem::Specification#gem_dir
,但它总是返回相对于安装目录的路径,即使gem实际上并不存在,这使得它在开发环境中无用。
答案 0 :(得分:1)
您始终可以使用提供的回溯功能:
caller.first
它生成文件和行的混合,但通常由:
分隔。我会小心地通过忽略行信息但保留其余部分来允许因任何原因可能包含冒号的文件名或路径。换句话说,请split
而不是sub
:
caller.first.sub(/:\d+:in .*$/, '')