【问题标题】:Ruby path managementRuby 路径管理
【发布时间】:2010-10-28 22:24:28
【问题描述】:

在 ruby​​ 程序中管理 require 路径的最佳方法是什么?

让我举一个基本的例子,考虑如下结构:

\MyProgram

\MyProgram\src\myclass.rb

\MyProgram\test\mytest.rb

如果在我的测试中我使用require '../src/myclass',那么我只能从\MyProgram\test 文件夹调用测试,但我希望能够从任何路径调用它!

我想出的解决方案是在所有源文件中定义以下行:

ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(ROOT) 然后总是使用require "#{ROOT}/src/myclass"

有没有更好的方法?

【问题讨论】:

    标签: ruby relative-path


    【解决方案1】:

    从 Ruby 1.9 开始,您可以使用 require_relative 来执行此操作:

    require_relative '../src/myclass'
    

    如果您在早期版本中需要此功能,您可以按照 this SO comment 从扩展 gem 中获取它。

    【讨论】:

      【解决方案2】:

      这里有一个稍微修改的方法:

      $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "src"))
      

      通过将源路径添加到 $LOAD_PATH(又名 $:),您无需在需要代码时明确提供根目录等,即 require 'myclass'

      【讨论】:

        【解决方案3】:

        恕我直言,同样,噪音更小:

        $:.unshift File.expand_path("../../src", __FILE__)
        require 'myclass'
        

        或者只是

        require File.expand_path "../../src/myclass", __FILE__
        

        在 (Debian) Linux 上使用 ruby​​ 1.8.7 和 1.9.0 进行测试 - 请告诉我它是否也适用于 Windows。

        为什么标准库中没有内置更简单的方法(例如,'use'、'require_relative' 或 sg 等)?更新:require_relative 从 1.9.x 开始就存在

        【讨论】:

        • 虽然它让我的脊椎发麻,但这是迄今为止我在 ruby​​ 的 inside 中看到的最佳选择。
        • 也就是说,我更喜欢将路径附加(而不是前置)到 ruby​​ 路径,因为您不会无意中踩到标准 ruby​​ 库中存在的东西。
        • 你不是说“我更喜欢前置(而不是附加)”吗? (换句话说:你真的不想确保你的东西优先吗?)我原来的例子是附加的'$:
        • Matt,“到目前为止,我在 ruby​​ 中看到的最佳选择”——在 ruby​​ 之外还有其他选择吗?比如预处理器之类的?
        • @inger,在 ruby​​ 之外执行此操作的选项是 shell 变量和 ruby​​ 命令行参数。
        【解决方案4】:
        Pathname(__FILE__).dirname.realpath
        

        以动态方式提供绝对路径。

        【讨论】:

          【解决方案5】:

          使用以下代码要求特定文件夹中的所有“rb”文件 (=> Ruby 1.9):

          path='../specific_folder/' # relative path from current file to required folder
          
          Dir[File.dirname(__FILE__) + '/'+path+'*.rb'].each do |file|
            require_relative path+File.basename(file) # require all files with .rb extension in this folder
          end
          

          【讨论】:

            【解决方案6】:

            sris 的回答是标准方法。

            另一种方法是将您的代码打包为 gem。然后 ruby​​gems 将负责确保您的库文件在您的路径中。

            【讨论】:

              【解决方案7】:

              这就是我最终得到的——setenv shell 脚本的 Ruby 版本:

                # Read application config                                                       
              $hConf, $fConf = {}, File.expand_path("../config.rb", __FILE__)
              $hConf = File.open($fConf) {|f| eval(f.read)} if File.exist? $fConf
              
                # Application classpath                                                         
              $: << ($hConf[:appRoot] || File.expand_path("../bin/app", __FILE__))
              
                # Ruby libs                                                                     
              $lib = ($hConf[:rubyLib] || File.expand_path("../bin/lib", __FILE__))
              ($: << [$lib]).flatten! # lib is string or array, standardize                     
              

              然后我只需要确保这个脚本在其他任何事情之前被调用一次,并且不需要触及各个源文件。

              我在配置文件中放置了一些选项,例如外部(非 gem)库的位置:

              # Site- and server specific config - location of DB, tmp files etc.
              {
                :webRoot => "/srv/www/myapp/data",
                :rubyLib => "/somewhere/lib",
                :tmpDir => "/tmp/myapp"
              }
              

              这对我来说效果很好,只需更改配置文件中的参数,我就可以在多个项目中重用 setenv 脚本。比 shell 脚本更好的替代方案,IMO。

              【讨论】:

              • @j-g-faustus:“将 __ FILE __ 与工作目录合并确保我可以从任何地方调用它”: File.expand_path(path, base) 应该具有相同的效果。您确定上面的英格回答没有完成这项工作吗?这给了你什么? (例如放在 test.rb 中): "puts File.expand_path "../../src/myclass", __ FILE __ "
              • 你是对的,File.expand_path 也是如此。我已经更新了帖子。它确实变得更干净了,谢谢 :) 除此之外,主要区别在于这是一个在应用程序启动时运行一次的单独脚本,我不需要接触各个源文件。
              猜你喜欢
              • 2010-09-29
              • 1970-01-01
              • 1970-01-01
              • 2017-05-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-10-02
              • 2021-11-20
              相关资源
              最近更新 更多