是否有更短的方法要求位于同一目录中的文件(正在执行的脚本)?
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
......但这只是邪恶的! ; - )
答案 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不会导致双重要求。
puts "start test A"
require 'testb'
require './testb'
puts "finish test A"
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'
#...