iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 13
1

什麼是 模組 (module)

昨天介紹完class後,今天來談談模組(module),不知道你們小時候有沒有玩過RPG類型的遊戲,如果有 你可以想像一下,當你的角色想要學習更厲害的招式技能時,可能會需要有技能包才能學習,模組就像是技能包這樣。

在Ruby裡,類別跟模組是很相似的,我們來試試看

puts Class.superclass 
#=> Module

當我們想找class的上層時,會得到 Module 這個類別,「類別」是「模組」的後代,類別根本就是繼承自模組來的。

那差別是什麼?

# 前、後代的實體方法差異:
p Class.instance_methods - Module.instance_methods

#=>[:allocate, :new, :superclass]

allocate 跟 new 跟產生實體(instance)有關,superclass 跟繼承有關。

也就是說,類別比模組多了可以「產生實體」的能力以及「繼承」的能力。

整理一下上面的重點

1.模組沒辦法 new 一個新的實體出來。
2.模組沒辦法繼承別的模組。

那要怎麼使用模組呢?

在Ruby定義模組, 使用的是 module

module Flyable  #定義模組跟類別一樣,開頭都要大寫
  def fly
    puts "I can fly!"
  end
end

寫好模組後 要套用到類別裡,使用include

class Bird
  include Flyable
end

kitty = Bird.new
kitty.fly        # => I can fly!

這樣Bird就有飛行的方法囉

如何透過 include prepen 和 extend 來引入 Module。

include

加入模組最常用到的是 include。
當一個 class 使用 include 引入 Module 的時候,會將 Module 內的 method 增加為自己的 instance method:

module Commentable
  def comment
    'I love comments!'
  end
end

class Post
  include Commentable
end

class Quote
  include Commentable
end

Post.new.comment  # => "I love comments!"
Quote.new.comment # => "I love comments!"

Post.ancestors  # => [Post,  Commentable, Object, Kernel, BasicObject]
Quote.ancestors # => [Quote, Commentable, Object, Kernel, BasicObject]

prepend

而如果使用prepend 來引入 Module, 則會放在繼承練的下方

https://ithelp.ithome.com.tw/upload/images/20190927/20118842ZKOjsRfRMp.png

module Commentable
  def comment
    'I love comments!'
  end
end

class Post
  prepend Commentable
  
  def comment
    'Post and comment'
  end
end


Post.new.comment # => "I love comments!"
Post.ancestors   # => [Commentable, Post, Object, Kernel, BasicObject]

extend

extend 則是會將 Module 引入到 class 的 singleton class 上方。
也就是說 Module 的 method 會變成 class mehtod
https://ithelp.ithome.com.tw/upload/images/20190927/20118842cYCDKQheUR.png

module Commentable
  def comment
    'I love comments!'
  end
end

class Post
  extend Commentable
end

Post.comment                     # => "I love comments!"
Post.singleton_class.ancestors   # => [#<Class:Post>, Commentable, ...]

參考資料:
Ruby 語法放大鏡之「類別跟模組有什麼不一樣?」
Ruby 的繼承鍊 (2) — Module 的 include、prepend 和 extend
Modules in Ruby: Part I


上一篇
DAY12 類別(Class)
下一篇
DAY14 Ruby on Rails 中的 Gemfile
系列文
毫無基礎學習 Ruby on Rails 的 甘苦心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言