1

我一直在处理我的第一个 Ruby 项目,在尝试将我的文件组织到不同目录的过程中,我遇到了让 .rb 文件加载自己本地的非 ruby​​ 文件(例如 .txt 文件)的问题.

例如,假设一个项目具有以下结构:

myproject/
    bin/
        runner.rb
    lib/
        foo.rb
        fooinfo.txt
    test/
        testfoo.rb

文件内容如下:

跑步者.rb

require_relative '../lib/foo.rb'

foo.rb

File.open('./fooinfo.txt') do |file|
    while line = file.gets
        puts line
    end
end

如果我 cd 到 lib 并运行 foo.rb,它可以轻松地在自己的目录中找到 fooinfo.txt 并打印其内容。但是,如果我 cd 到 bin 并运行 runner.rb,我会得到

in `initialize': No such file or directory - ./fooinfo.txt (Errno::ENOENT)

我认为这是因为 File.open 搜索相对于运行顶级程序的任何目录。有没有办法确保 foo.rb 可以找到 fooinfo.rb 而不管它是从哪里运行/需要的(假设 foo.rb 和 fooinfo.rb 始终保持相对于彼此的相同位置)?我希望能够从 bin/runner.rb 运行 foo.rb,并在 test/ 中运行一个测试文件,并让它能够在这两种情况下找到 fooinfo.txt。

理想情况下,我希望有一个即使移动整个 myproject 目录也能工作的解决方案。

是否有类似 require_relative 的东西可以找到非 ruby​​ 文件?

4

2 回答 2

2

尝试使用__FILE__andFile.dirname构建绝对路径。例如:

File.open(File.expand_path(File.dirname(__FILE__)) + './fooinfo.txt') do |file|
   ...
end
于 2012-07-12T21:04:54.343 回答
0

在这种情况下,最简单的事情就是改变

File.open('./fooinfo.txt')

File.open('../lib/fooinfo.txt')

这将从项目根目录下的任何项目子目录(包括lib/)中直接工作。

在大型项目中有用的更强大的解决方案是拥有一个PROJECT_ROOT可以在任何地方使用的常量。如果您有lib/const.rb

module Const
  PROJECT_ROOT = File.expand_path("..", File.dirname(__FILE__))
end

然后(假设您已经require编辑了该文件)您可以使用:

File.open(Const::PROJECT_ROOT + '/lib/fooinfo.txt')
于 2012-07-12T23:21:57.857 回答