__FILE__指向rvm

时间:2017-11-30 23:24:29

标签: ruby rubygems

我有一个奇怪的问题,即宝石的可执行文件中的__FILE__指向的位置不应该是$PROJECT_ROOT/bin而不是$GEM_HOME/bin)。它发生在Ruby 2.4.1但没有其他版本的MRI Ruby或JRuby。此外,只有脚本从项目根目录运行才会发生。我在https://bugs.ruby-lang.org/issues/14144发布了一个关于Ruby语言的错误报告。以下是该报告,粘贴在下面,并在此修改为适当性:

使用https://github.com/keithrbennett/underscore_file_test处的Github仓库可以说明此问题。

当:

Ruby version == 2.4.1 and current directory is the project root of this project and the gem is built and installed and the executable is run from the gem without preceding it with 'ruby' and the executable is run without specifying a directory (i.e. as 'underscore_file_test', not 'bin/underscore_file_test')

然后:

__FILE__ => $PROJECT_ROOT/exe/underscore_file_test

而不是指向GEM_PATH中的目录,如:

__FILE__ => /Users/kbennett/.rvm/gems/ruby-2.4.1/bin/underscore_file_test

Ruby 2.4.1发生了这个错误,但没有:

  • ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-darwin15.6.0]
  • ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]
  • ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]
  • jruby 9.1.7.0 (2.3.1) 2017-01-11 68056ae Java HotSpot(TM) 64-Bit Server VM 25.77-b03 on 1.8.0_77-b03 +jit [darwin-x86_64]

我的开发机器是运行MacOs Sierra的MacBookPro。 uname -a输出为:

Darwin MacBook-Pro-KB-13.local 16.7.0 Darwin Kernel Version 16.7.0: Wed Oct 4 00:17:00 PDT 2017; root:xnu-3789.71.6~1/RELEASE_X86_64 x86_64

重现步骤:

1) Download or git clone the Github project tree, or the attached tarball.
2) Change directory to the project root.
3) Run: clear; gem build *gemspec && gem install *gem && underscore_file_test
4) Note the directory component of the output.

如果你在其他地方cd,输出将是正确的, 即将位于GEM_PATH目录中。

如果使用不同的Ruby从项目根运行命令, 它可能会奏效。我没有在2.4.1之后的版本上测试过这个。

2 个答案:

答案 0 :(得分:0)

这似乎是一个rvm问题。当我将gem卸载rvm的executable_hooks gem时,行为将是正确的;当我重新安装它时,它会再次出错。

我做了rvm remove 2.4.1,然后是rvm install 2.4.1 --with-openssl-dir=/usr/local/opt/openssl,问题就消失了。

请注意,必须执行rvm remove而不只是rvm uninstall。有关差异的解释,请参阅https://rvm.io/rubies/removing

答案 1 :(得分:0)

__FILE__指示实际上可能是符号链接,而不是实际的目标文件。要查找您实际指向的文件,您可能需要解决它:

file = __FILE__
while (File.symlink?(file))
  file = File.readlink(file)
end

这将保留以下符号链接,直到它到达原始符号。这通常只适用于符号链接的二进制文件,RVM和它经常使用的工具,但不适用于通常保留原样的库文件。

您可以通过为二进制存根创建符号链接并直接调用此代码来测试此代码是否正常工作:

ln -s test.rb symlink.rb
ruby symlink.rb

你会得到正确的道路。

Ruby的require_relative似乎确实为您处理了此问题,但如果您使用__FILE__手动构建路径,则在解析时必须牢记这一点。