有没有更短的方法来在ruby中的同一目录中要求一个文件?

时间:2009-04-25 08:43:42

标签: ruby path require

是否有更短的方法要求位于同一目录中的文件(正在执行的脚本)?

require File.expand_path(File.dirname(__FILE__) + '/some_other_script')

我读到require "my_script"require "./my_script"实际上会加载脚本两次(ruby将无法识别它实际上是相同的脚本),这就是为什么推荐File.expand_path的原因:如果每次需要脚本时都使用它,那么它只会被加载一次。

对我来说,像Ruby这样的简洁语言似乎没有更短的解决方案,这似乎很奇怪。例如,python只有这个:

import .some_other_module_in_the_same_directory

我想我可以修补require ......但这只是邪恶的! ; - )

4 个答案:

答案 0 :(得分:90)

从ruby 1.9开始,您可以使用require_relative

答案 1 :(得分:12)

只需要filename

是的,如果您将其指定为filename./filename,它会导入两次,所以请勿这样做。您没有指定.rb,因此请勿指定路径。我通常会将大部分应用程序逻辑放入lib中的文件中,然后在bin中创建一个类似于以下内容的脚本:

#!/usr/bin/env ruby

$: << File.join(File.dirname(__FILE__), "/../lib")
require 'app.rb'
App.new.run(ARGV)

另一个优点是,如果加载应用程序逻辑没有自动开始执行它,我发现单元测试更容易。

答案 2 :(得分:3)

即使您从其他目录运行脚本,上述操作也会起作用。 但是,在同一目录中,您引用的较短表单按预期工作,至少对于ruby 1.9不会导致双重要求。

testa.rb

puts "start test A"
require 'testb'
require './testb'
puts "finish test A"

testb.rb

puts "start test B"
puts "finish test B"

运行'ruby testa.rb'将导致:

start test A
start test B
finish test B
finish test A

但是,较长的表单甚至可以从另一个目录中运行(例如,ruby somedir / script.rb)

答案 3 :(得分:3)

将它放在标准库目录中(已经在默认加载路径$:中的某个位置):

# push-loadpath.rb
if caller.first
  $: << File.expand_path(File.dirname(caller.first))
end

然后,这应该工作

% ls /path/to/
bin.rb lib1.rb lib2.rb #...
% cat /path/to/bin.rb
load 'push-loadpath.rb'
require 'lib1'
require 'lib2'
#...

caller使您可以访问当前的callstack,并告诉您哪个文件和位置,因此push-loadpath.rb使用该文件将load添加到加载路径中的文件。< / p>

请注意,您应该load该文件,而不是require,因此可以多次调用正文(每次要更改加载路径时一次)。

或者,您可以将方体包裹在一个方法中,

# push-loadpath.rb
def push_loadpath
  $: << File.expand_path(File.dirname(caller.first))
end

这将允许你require,并以这种方式使用它:

% ls /path/to/
bin.rb lib1.rb lib2.rb #...
% cat /path/to/bin.rb
require 'push-loadpath'
push_loadpath
require 'lib1'
require 'lib2'
#...