【问题标题】:Ruby 1.9.3 - Locate file local to ruby program regardless of where program is called fromRuby 1.9.3 - 定位 ruby​​ 程序的本地文件,无论从何处调用程序
【发布时间】:2012-07-12 21:00:31
【问题描述】:

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

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

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

文件内容如下:

runner.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,我会得到 ​​p>

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​​ 文件?

【问题讨论】:

    标签: ruby file require directory-structure


    【解决方案1】:

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

    File.open(File.expand_path(File.dirname(__FILE__)) + './fooinfo.txt') do |file|
       ...
    end
    

    【讨论】:

    • 我认为 './fooinfo.txt' 应该只是 '/fooinfo.txt' (至少,第一个在我测试时不起作用,但第二个起作用)。除此之外,即使 foo 和 fooinfo 被移动到不同的目录,我也喜欢这个解决方案。
    【解决方案2】:

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

    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
    

    那么(假设你已经requireed 那个文件)你可以使用:

    File.open(Const::PROJECT_ROOT + '/lib/fooinfo.txt')
    

    【讨论】:

    • 第一个解决方案有点局限,但我喜欢你在第二个解决方案中提出的将根存储在常量中的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多