# 有時候會看到有兩個冒號寫法是什麼意思？

> 

Published: 2015-04-19
URL: https://kaochenlong.com/namespace

---

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


