2017-04-20 56 views
1

嘗試創建基於bundler's official guide on developing a Ruby gem的寶石。Ruby:需要在寶石中工作,從源代碼運行時失敗

運行bundle gem foodie將在lib目錄中創建一個結構和生成文件:

  • 美食家
    • version.rb
  • foodie.rb

美食家。 rb讀取

require "foodie/version" 

module Foodie 
    # Your code goes here... 
end 

運行ruby lib/foodie.rb(或者也可在不同的目錄)將導致

C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- foodie/versio 
n (LoadError) 
     from C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 
     from foodie.rb:1:in `<main>' 

在另一方面通過rake install安裝寶石,然後要求創業板工作得很好。

它從源頭上運行,如果require "foodie/version"更改爲require_relative "foodie/version"在foodie.rb。據我瞭解基於模塊

  • require_relative作品基於目錄結構
  • 對我來說,後者看起來像一個黑客

    • require作品。通過模塊來構建代碼不再有意義,因爲它不會被強制執行(也許它仍然有意義,但是你可以犯錯並永遠不會注意到)。

      我的問題是:

      • 是否有可能測試來自源的寶石,而無需安裝它,而以下所述捆綁約定(使用require代替require_relative)?
      • 爲什麼安裝後的寶石工作?
      • 是否有任何使用require,require_relative,模塊,文件和一般結構的最佳做法?

      謝謝。

    +0

    請把這個問題分解成單獨的問題,因爲:1.你所問的三個問題是完全不同的,2.他們將以這種方式對未來的讀者更有用。謝謝! –

    +0

    感謝您的反饋。我是這樣問的,因爲這些問題出自相同的問題/背景 - 我想像其他人在類似的情況下也有類似的問題。我認爲每個問題都需要相同的背景。在幾個問題上重複相同的背景是不是很好的做法? – thisismydesign

    回答

    1

    您需要將您的lib目錄添加到Ruby的加載路徑。加載路徑是Ruby在您撥打require時搜索文件的目錄列表。當您使用gem時,Rubygems也管理加載路徑,這就是您的代碼作爲gem安裝時工作的原因。

    你說「據我所知... require作品基於模塊」,這是不正確的。 require與文件一起工作,它只是約定,一個類或模塊被定義在具有匹配名稱的文件中,例如, MyModule可能位於my_module.rb

    有幾種方法可以將dir添加到加載路徑。如果你想避免輸入-I lib您可以使用RUBYLIB環境變量

    $ ruby -I lib lib/foodie.rb 
    

    :在命令行中,你可以使用-I選項。紅寶石增加了這樣的內容負載路徑:(在Windows上,我認爲你將需要使用set而非export

    $ export RUBYLIB=lib 
    $ ruby lib/foodie.rb 
    

    您也可以從withing程序本身操縱負載路徑。它存儲在全局變量$LOAD_PATH中,別名爲:$。這是Rubygems和Bundler如何管理你的寶石。

    +0

    謝謝!兩個評論/問題:1,我的假設是,即使你在一個文件中定義了幾個模塊和類,你也可以選擇只需要一個特定的類(例如'需要A/B/C'在一個文件中包含以下結構:'module A module B class C ... end end end')。有沒有辦法做到這一點? 2,對我來說,「require_relative」與「require」相同,只是前者具有擴展功能,因此應該是首選。您是否同意這一點,或者有沒有通常使用'require_relative'而不是'require'的缺點? – thisismydesign