有時候會看到有兩個冒號寫法是什麼意思?
隨便打開你 Rails 專案裡的 model 檔案,它可能會長得像這樣:
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
end
第一行後面那個 ActiveRecord::Base
裡面的 2 個冒號 ::
,各位知道是什麼意思嗎?
菜市場名
也許你也叫金城武(或自己覺得自己長得像金城武),然後我也剛好也很巧叫金城武,這樣在大街上大叫一聲帥哥就一堆人回頭了,不太好。
寫程式偶爾也會遇到這樣的狀況,舉例來說,如果大家剛好都有一個叫做 Animal
的類別或是 Flyable
的模組,放在同一個專案裡就會打架了。所以 Ruby 有設計 namespace 來解決這個問題。
在 Ruby 裡,因為 module
或 class
可以有巢狀結構(類別裡可以包模組,模組裡面可以包類別,就是大腸包小腸的概念啦),剛好可以拿來做 namespace 的包裝,例如:
module Utility
module Flyable
def fly
# ....
end
end
end
這樣一來,如果要使用 Flyable
這個類別的話:
class Cat
include Utility::Flyable
end
要 include 那個 Flyable 模組,就必須連名帶姓的 include,也就是「樹林::金城武」、「三重::劉德華」的概念。
除此之外,其實你也可把常數包在 namespace 裡:
module Utility
TaxRate = 10
module Flyable
Speed = 20
def fly
# ....
end
end
end
puts Utility::TaxRate # => 10
puts Utility::Flyable::Speed # => 20
要使用這些常數,也是一樣要提供完整的路徑給才行。(如果你知道的話,其實不管是類別或模組,它們的名字基本上也就是常數而已)
所以,原來這段程式範例:
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
end
它的意思就是說有一個叫做 Post
的類別,它是繼承自某個放在 ActiveRecord
的模組(或類別)裡的 Base
類別。如果去 github 上翻 Rails 的原始碼的話(連結),應該可以看到這段:
module ActiveRecord
# .....
# 中略
# .....
class Base
extend ActiveModel::Naming
extend ActiveSupport::Benchmarkable
extend ActiveSupport::DescendantsTracker
extend ConnectionHandling
extend QueryCache::ClassMethods
# ... 略
end
end
的確是有一個 ActiveRecord
的模組,裡面包了一個 Base
的類別沒錯 :)
工商服務
實體課程:Ruby on Rails 實戰課程
線上課程:五倍學院線上課程