簡體   English   中英

將目錄添加到$ LOAD_PATH(Ruby)

[英]Adding a directory to $LOAD_PATH (Ruby)

我已經看到了兩種將當前正在執行的文件目錄添加到$ LOAD_PATH(或$ :)中的常用技術。 如果您不使用gem,我會看到這樣做的好處。 顯然,一個人比另一個人更冗長,但是是否有理由將一個人放在另一個人身上?

第一種冗長的方法(可能會過大):

$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))

更直接,快捷和骯臟:

$:.unshift File.dirname(__FILE__)

有什么理由要互相反對嗎?

Ruby的加載路徑通常被看成$:,但是僅僅因為它很短就不能改善它。 如果您更喜歡清晰而不是機靈,或者出於簡潔目的讓自己發癢,那么就不必因為其他所有人都那么做。 打招呼 ...

$LOAD_PATH

...再見...

# I don't quite understand what this is doing...
$:

我想說的是$:.unshift File.dirname(__FILE__) ,而不是另一個,僅僅是因為我在代碼中看到的使用量比$LOAD_PATH一個要$LOAD_PATH ,而且它也更短!

我不太喜歡“快速而骯臟”的方式。 Ruby新手都會考慮$:. 是。

我發現這更加明顯。

libdir = File.dirname(__FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)

或者,如果我在乎完整的路徑...

libdir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)

更新 2009/09/10

到目前為止,我一直在進行以下操作:

$:.unshift(File.expand_path(File.dirname(__FILE__))) unless
    $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))

瀏覽GitHub時,我在許多不同的ruby項目中都看到了它。

似乎是慣例?

如果在Rails項目中鍵入script/console並輸入$: :,則會得到一個數組,其中包含加載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 

注意我如何告訴代碼塊對字符串“ models”,“ controllers”和“ models”執行代碼塊內的動作,在其中重復“ models”。 (僅供參考, %w{ ... }是告訴Ruby保存字符串數組的另一種方法)。 運行script/console ,鍵入以下內容:

>> puts $:

而且我鍵入了它,以便更輕松地讀取字符串中的內容。 我得到的輸出是:

...
...
./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程序員,那么您可能對自己正在做的事情非常了解,並且可能不會犯重復路徑的錯誤。 如果您是新手,我會花更長的時間,直到您真正了解自己在做什么。

最好我遇到了使用Rspec時通過相對路徑添加目錄的問題。 我覺得它很詳細,但仍然是一個不錯的選擇。

$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))

有一個gem可以讓您使用更好更干凈的代碼來設置加載路徑。 檢查一下: https : //github.com/nayyara-samuel/load-path

它也有很好的文檔

我知道第一次提出這個問題已經有很長時間了,但是我還有一個要分享的答案。

我有另一位程序員幾年來開發的Ruby應用程序,盡管它們可能訪問相同的數據庫,但它們在不同的應用程序中重用了相同的類。 由於這違反了DRY規則,因此我決定創建一個類庫,以供所有Ruby應用程序共享。 我本可以將其放在主要的Ruby庫中,但這會在我不想做的通用代碼庫中隱藏自定義代碼。

我遇到了一個問題,在已經定義的名稱“ profile.rb”和我使用的類之間存在名稱沖突。 在我嘗試創建通用代碼庫之前,這個沖突才不是問題。 通常,Ruby首先搜索應用程序位置,然后轉到$ LOAD_PATH位置。

application_controller.rb找不到我創建的類,並且由於它不是類,因此在原始定義上引發了錯誤。 由於我從應用程序的app / models部分中刪除了類定義,因此Ruby在此處找不到它,並在Ruby路徑中尋找它。

因此,我修改了$ LOAD_PATH變量,以包括我正在使用的庫目錄的路徑。 可以在初始化時在environment.rb文件中完成此操作。

即使將新目錄添加到搜索路徑中,Ruby也會拋出錯誤,因為它優先考慮首先使用系統定義的文件。 $ LOAD_PATH變量中的搜索路徑優先優先搜索Ruby路徑。

因此,我需要更改搜索順序,以便Ruby在搜索內置庫之前在我的公共庫中找到該類。

這段代碼是在environment.rb文件中完成的:

Rails::Initializer.run do |config|

* * * * *

path = []
path.concat($LOAD_PATH)
$LOAD_PATH.clear
$LOAD_PATH << 'C:\web\common\lib'
$LOAD_PATH << 'C:\web\common'
$LOAD_PATH.concat(path)

* * * * *

end

我認為您不能在此級別上使用之前提供的任何高級編碼結構,但是如果您想在應用程序的初始化時進行設置,它就可以正常工作。 將$ LOAD_PATH變量添加回新變量時,必須保持其原始順序,否則某些主要的Ruby類會丟失。

在application_controller.rb文件中,我只是使用

require 'profile'
require 'etc' #etc

這會為整個應用程序加載自定義庫文件,即,我不必在每個控制器中都使用require命令。

對我來說,這就是我一直在尋找的解決方案,我想我會將其添加到此答案中以傳遞信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM