1. 程式人生 > >Ruby中迴圈引用的檢查方法

Ruby中迴圈引用的檢查方法

我們知道在Ruby中要引用外部庫,有兩種方法:require和load。
他們的作用都是從外部引用一個庫到本檔案中,區別是require是僅引用一次,多次require不會重複載入檔案,且require不需要字尾,如:要引用a.rb檔案,則:

rquire 'a'

而load會重複載入,load一次載入一次檔案,且load要寫全檔名稱:

load 'a.rb'

詳細的關於require和load的區別可以參考ruby require vs load

我們還知道,要使用require需要將檔案放到ruby的lib目錄下,還有一種方式就是修改ruby的$LOAD_PATH,實際上require就是修改了$LOAD_PATH,$LOAD_PATH的另外一種表達方式是 $:,我們可以輸出這兩個變數

1.9.3-p125 :002 > $LOAD_PATH
=> ["~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/site_ruby/1.9.1", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/site_ruby/1.9.1/x86_64-darwin11.4.0", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/site_ruby", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/vendor_ruby/1.9.1", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/vendor_ruby/1.9.1/x86_64-darwin11.4.0", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/vendor_ruby", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/x86_64-darwin11.4.0"]
1.9.3-p125 :003 > $:
=> ["~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/site_ruby/1.9.1", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/site_ruby/1.9.1/x86_64-darwin11.4.0", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/site_ruby", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/vendor_ruby/1.9.1", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/vendor_ruby/1.9.1/x86_64-darwin11.4.0", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/vendor_ruby", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1", "~/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/x86_64-darwin11.4.0"]
1.9.3-p125 :004 >

好了,現在我們要require自己的檔案怎麼辦?一般的ruby專案中都有多個檔案且他們之間有依賴關係,如a.rb依賴b.rb。我們不能使用require,require對目錄有要求。在ruby 1.9版本中提供了require_relative,可以指定相對或絕對路徑,不一定要是在ruby的系統目錄下。如:

#!/usr/local/ruby/bin/ruby
require_relative './main_service'

#start....
pmu_server = PMU_Service::PMUServer.get_instance
pmu_server.start_fcgi

要注意的問題是,當專案越來越大的檔案越來越多的時候,這時候依賴關係會越來越複雜,容易出現迴圈依賴。
ruby是動態語言不能提前編譯發現問題,但是,實際上是有替代方法的。
我們可以把專案中所有檔案串起來,執行 ruby -w ,-w的意思是輸出告警,相當於是語法檢查,也相當於編譯的效果了。

當代碼有迴圈引用的時候,ruby -w也可以檢查出來:

~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_handler.rb:6: warning: loading in progress, circular require considered harmful - ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_service.rb
from main_service.rb:7:in `

'
from main_service.rb:7:in `require_relative'
from ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_service.rb:7:in `'
from ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_service.rb:7:in `require_relative'
from ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_handler.rb:6:in `'
from ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_handler.rb:6:in `require_relative'

所以強烈推薦使用 ruby -w 檢查語法警告,在專案執行之前。

要強調的是:迴圈引用並不僅僅是警告,而會直接導致專案執行失敗。