将目录添加到$ LOAD_PATH(Ruby)

Mar*_*k W 90 ruby rubygems load-path

我已经看到两种常用的技术,用于将当前正在执行的文件的目录添加到$ LOAD_PATH(或$ :).如果你不使用宝石,我会看到这样做的好处.显然,一个看起来比另一个看起来更冗长,但有理由与其中一个相提并论吗?

第一个,冗长的方法(可能是过度杀伤):

$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
Run Code Online (Sandbox Code Playgroud)

而且更直接,快速和肮脏:

$:.unshift File.dirname(__FILE__)
Run Code Online (Sandbox Code Playgroud)

有理由和其他人一起去吗?

小智 146

Ruby加载路径通常被视为$:,但仅仅因为它很短,不会使它变得更好.如果你喜欢清晰到聪明,或者因为简洁本身就会让你发痒,你不需要仅仅因为其他人都这样做.打招呼 ...

$LOAD_PATH
Run Code Online (Sandbox Code Playgroud)

......告别......

# I don't quite understand what this is doing...
$:
Run Code Online (Sandbox Code Playgroud)

  • 此外,对于像"$:"这样只包含符号的字符串,谷歌要难得多. (28认同)

Rya*_*igg 49

我会说与$:.unshift File.dirname(__FILE__)另一个相比,只是因为我在代码中看到它的使用比它更多$LOAD_PATH,而且它也更短!

  • 取决于您为项目遵循的样式指南.流行的[Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide#syntax)说:"避免使用Perl风格的特殊变量(如$:,$;等).它们是我们不鼓励他们使用除了单行脚本以外的任何东西." (8认同)

Luk*_*ins 22

我不太喜欢"快速而肮脏"的方式.任何刚接触Ruby的人都会思考什么$:.是.

我发现这更明显.

libdir = File.dirname(__FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
Run Code Online (Sandbox Code Playgroud)

或者,如果我关心完整的道路......

libdir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
Run Code Online (Sandbox Code Playgroud)

更新 2009/09/10

最近我一直在做以下事情:

$:.unshift(File.expand_path(File.dirname(__FILE__))) unless
    $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
Run Code Online (Sandbox Code Playgroud)

我在浏览GitHub时在一大堆不同的ruby项目中看到过它.

似乎是惯例?

  • RuboCop 告诉我可以使用 `__dir__` 来获取当前文件目录的路径。 (2认同)

小智 8

如果您键入script/consoleRails项目并输入$:,您将获得一个包含加载Ruby所需的所有目录的数组.这个小练习的外卖$:是阵列.既然如此,您可以在其上执行函数,例如在unshift方法或<<运算符之前添加其他目录.正如你在声明中暗示的那样,$:并且$LOAD_PATH是一样的.

如上所述,以快速和脏的方式执行此操作的缺点是:如果您已在引导路径中具有该目录,则它将重复自身.

例:

我有一个名为todo的插件.我的目录结构如下:

/---vendor
  |
  |---/plugins
        |
        |---/todo
              |
              |---/lib
                    |
                    |---/app
                          |
                          |---/models
                          |---/controllers
              |
              |---/rails
                    |
                    |---init.rb

在init.rb文件中,我输入了以下代码:

## In vendor/plugins/todo/rails/init.rb
    %w{ models controllers models }.each do |dir|
      path = File.expand_path(File.join(File.dirname(__FILE__), '../lib', 'app', dir))
      $LOAD_PATH << path
      ActiveSupport::Dependencies.load_paths << path
      ActiveSupport::Dependencies.load_once_paths.delete(path)
    end 
Run Code Online (Sandbox Code Playgroud)

请注意我如何告诉代码块执行块内部对字符串'models','controllers'和'models'的操作,我重复'models'.(仅供参考,这%w{ ... }是告诉Ruby保存字符串数组的另一种方法).当我跑步时script/console,我键入以下内容:

>> puts $:
Run Code Online (Sandbox Code Playgroud)

我输入这个,以便更容易读取字符串中的内容.我得到的输出是:

...
...
./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/models
./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/controllers
./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/models

正如您所看到的,虽然这是一个简单的示例,我可以在使用我正在处理的项目时创建,如果您不小心,快速和脏的方式将导致重复路径.较长的方法将检查重复的路径并确保它们不会发生.

如果你是一位经验丰富的Rails程序员,你可能对你正在做的事情非常了解,并且可能不会错误地重复路径.如果你是一个新手,我会用更长的路去,直到你真正了解你在做什么.


Dav*_*son 7

最好我在使用Rspec时通过相对路径添加dir.我发现它足够冗长,但仍然是一个很好的一个班轮.

$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
Run Code Online (Sandbox Code Playgroud)