2010-09-08 69 views

回答

255

試想一下,在docs

require_relative通過允許您加載一個文件,它是相對於包含require_relative聲明文件補充內置的方法require

例如,如果您有測試下他們在「測試」目錄單元測試類和數據「的測試/ data」目錄,那麼你可能會使用這樣的線在測試案例:

require_relative "data/customer_data_1" 
+20

'require'./file.rb''和'require_relative'file.rb''之間有區別嗎? – 2014-10-25 17:31:31

+49

@CiroSantilli是的。 'require_relative'允許你「加載一個相對於包含'require_relative'語句的文件**'的文件。用'require','。/'表示一個相對於你當前工作目錄的路徑。 – Ajedi32 2014-11-14 15:58:06

+8

我認爲更重要的是要注意'require str'將總是在$ LOAD_PATH中搜索目錄。當您需要加載的文件存在於相對於調用加載的文件的地方時,您應該使用'require_relative'。爲「外部」依賴保留'require'。 – rthbound 2015-09-30 06:16:38

69

從紅寶石API

require_relative補充 內置方法需要通過允許您 加載文件,它是相對於到t他 文件包含require_relative 聲明。

當您使用需要加載一個文件, 你通常訪問在 系統 功能,已經正確安裝 ,和加以利用。要求不提供 好的解決方案,用於在 項目的代碼中加載文件。在開發階段, 可能有用, 訪問測試數據,或者甚至 訪問項目內「鎖定」 的文件,而不打算用於 外部使用。

例如,如果您有單元測試 班「測試」目錄,測試 「測試/數據」目錄下 數據對他們來說,那麼你可能 使用這樣的線在測試用例:

require_relative "data/customer_data_1" 

因爲無論 「測試」,也不是「測試/數據」可能 是Ruby的庫路徑(和 很好的理由),一個正常的要求不會 找到他們。對於這個特定的問題,require_relative是一個很好的解決方案 。

您可以包含或省略文件 正在加載的擴展名 (.rb或.so)。

路徑必須響應to_str。

你可以找到http://extensions.rubyforge.org/rdoc/classes/Kernel.html

11

我剛纔看到的RSpec的代碼的文檔對require_relative爲O(1)恆和require是O(N)線性一些評論。所以可能的區別是require_relative是比require更受歡迎的。

+0

有趣。我在這裏登陸尋找有關速度比較的信息。我的想法是'require_relative'更快,因爲加載器不必遍歷負載路徑來搜索文件。本質上,'require_relative'提供了一個直接的鏈接。 – 2015-01-29 23:53:08

+0

儘早討論[require_relative速度](https://www.ruby-forum.com/topic/2990962)和RSpec [changelog](https://github.com/rspec/rspec-core/blob/master/ Changelog.md#280rc2--2011-12-19)。 – 2015-01-30 00:06:42

64

require_relativerequire

require_relative('path') 

一個方便的子集等於:

require(File.expand_path('path', File.dirname(__FILE__))) 

如果__FILE__被定義,或者它提高LoadError否則。

這意味着:

  • require_relative 'a'require_relative './a'要求相對當前文件__FILE__)。

    這就是你要在庫中使用時想要使用的內容,因爲你不想讓結果依賴於調用者的當前目錄。

  • eval('require_relative("a.rb")')增加LoadError,因爲__FILE__沒有在eval的內部定義。

    這就是爲什麼你不能在RSpec測試中使用require_relative,得到eval ed。

以下操作只能使用require

  • require './a.rb'要求相對當前目錄

  • require 'a.rb'使用搜索路徑($LOAD_PATH)要求。它沒有找到與當前目錄或路徑相關的文件。

    ,因爲文件說,當「文件名不能解析爲絕對路徑」(即具有/./../開始),這始終是File.expand_path的情況是路徑搜索只發生這是不可能的require_relative

下面的操作是可能的兩個,但你會想用require,因爲它是更短,更高效:

  • require '/a.rb'require_relative '/a.rb'都需要絕對路徑。

閱讀源

當文檔是不明確的,我建議你看一看源(切換源中的文檔)。在某些情況下,它有助於瞭解正在發生的事情。

要求:

VALUE rb_f_require(VALUE obj, VALUE fname) { 
    return rb_require_safe(fname, rb_safe_level()); 
} 

require_relative:

VALUE rb_f_require_relative(VALUE obj, VALUE fname) { 
    VALUE base = rb_current_realfilepath(); 
    if (NIL_P(base)) { 
     rb_loaderror("cannot infer basepath"); 
    } 
    base = rb_file_dirname(base); 
    return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level()); 
} 

這讓我們得出這樣的結論

require_relative('path') 

是一樣的:

require(File.expand_path('path', File.dirname(__FILE__))) 

因爲:

rb_file_absolute_path =~ File.expand_path 
rb_file_dirname1  =~ File.dirname 
rb_current_realfilepath =~ __FILE__ 
25

require使用當前目錄正在運行從

require_relative程序使用如該程序本身駐留

例如的目錄,如果一個程序在~/code和被稱爲1.rb你已經做了一個cd到該目錄

cd ~/code 

,你試着和

ruby 1.rb 

然後運行中1.rb

require './2.rb' 
require_relative '3.rb' 

兩個Ruby程序將正常工作。

但是如果你在其他目錄,說

cd ~/tmp 

,你試着和

ruby ../1.rb 

然後運行該程序你會得到一個錯誤,如

/home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- ./2.rb (LoadError) 
    from /home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require' 
    from ../1.rb:1:in `<main>' 

試試荷蘭國際集團使用

require './2.rb' 

而使用

require_relative '3.rb' 

仍然工程確定_because基準(以3.rb)是相對到哪個目錄程序(1.rb)位於英寸

0

我如果腳本在本地運行或從映射的網絡驅動器運行,但是從UNC \ servername \ sharename \ folde運行,則在使用Windows時可以使用require './1.rb'你需要使用的路徑require_relative './1.rb' 我不會在討論中混用其他原因。

+0

我想知道你是怎麼加載'require_relative'文件 能否請你拋出一個想法在這個 http://stackoverflow.com/questions/43487784/appiumruby-load-error-in-the-gem – 2017-04-19 07:02:49

8

最佳答案是正確的,但技術性很強。對於那些更新的紅寶石 -

  • require_relative將很可能用於從您編寫的另一個文件中引入代碼。

例如,如果你有~/my-project/data.rb數據,並要包含在~/my-project/solution.rb?在solution.rb中,您將添加require_relative 'data'

重要的是要注意這些文件不需要在同一個目錄中。 require_relative '../../folder1/folder2/data'也是有效的。

  • require將最有可能被用來從別人寫的庫中引入代碼。

例如,如果要使用active_support庫中提供的輔助函數之一,該怎麼辦?您需要安裝帶有gem install activesupport的gem,然後安裝文件require 'active_support'

require 'active_support/all' 
"FooBar".underscore 

說differently--

  • require_relative需要一個文件特別指出相對於調用它的文件。

  • require需要包含在$ LOAD_PATH中的文件。

+0

只有回答我明白了。 – CapturedTree 2017-10-11 05:50:28

+0

我該如何投票回答這個問題,並把它帶到最前面,這樣每個訪問者的問題頁面都會立即得到一個清晰可理解的答案,而不會突然冒出來呢? – GordonFreaman 2018-03-08 14:31:13

相關問題