Rails 所做的工作比我們想像的更複雜,以 Controller 的 nest namespace 來說, Rails 必須知道要去哪裡載入這個檔案
Rails 載入相關的 source 檔案時,必須要先解析 Ruby 的語法
也因此我們才可以用多種方式來定義 class
舉個例來說,假設我們寫了一個 MyController,但 Rails 不知道他是哪個模組下的 MyController,他會去猜,但不是百分百猜中
當你載入一個檔案並且呼叫 whatever_class.rb 時,無法確定這檔案裡面是不是有 whateverClass 的物件,甚至也無法確定 whateverClass 是不是一個 class。
使用 const_get 來自動載入,如果呼叫的方法裡面沒有相關的 class 就因為找不到而進入無限循環會壞掉
所以 const_get 不是一個好解法
所以我們來用 const_missing 處理這個狀況
而 const_missing 會再呼叫一次 const_get
# Rainbow/lib/rainbow/dependencies.rb
class Object
def self.const_missing(c)
return nil if @calling_const_missing
@calling_const_missing = true
require Rulers.to_underscore(c.to_s)
klass = Object.const_get(c)
@calling_const_missing = false
klass
end
end
如果目前有其他的 const_missing 正在執行中,那麼再次執行會回傳 nil
更改後記得要刪除 rainbow-0.0.2.gem
> gem build rainbow.gemspec
Successfully built RubyGem
Name: rainbow
Version: 0.0.2
File: rainbow-0.0.2.gem
> gem install rainbow-0.0.2.gem
Successfully installed rainbow-0.0.2
Parsing documentation for rainbow-0.0.2
Installing ri documentation for rainbow-0.0.2
Done installing documentation for rainbow after 0 seconds
1 gem installed
當我們改變 classes 時, Rails 會預先重新載入,我們需要重啟伺服器
當 controller 被呼叫時, Rails 使用一種方法去清除及打包所有的 classes
這就是為什麼 Rails 運作的比較慢的原因
我們可以用 rerun 這個套件達成 reloading 的效果
打開 Gemfile 並且在 development 加入 rerun 這個套件
group :development do
gem 'rerun', '~> 0.13.0'
gem 'listen', '~> 3.1', '>= 3.1.5'
end
rerun 是一個指令套件,偵測到你的檔案有改變時,會重啟你的 server 及程序
接下來執行
> bundle install
執行後重新跑 server
bundle exec rerun -- rackup -p 3001
這時 rerun 就會開始偵測檔案的變動囉!