昨天第14天的文章在研究.map和.collect的時候,有一句話提到map是collect的別名 (map is an alias for collect)。除了讓我學到alias這個英文單字之外,也意外發現,ruby裡面竟然有alias方法!
今天就來研究alias吧~
Day15 alias 和 alias_method比較? What's the difference between alias和 alias_method?
幾年前我剛出社會,得到第一份全職工作的時候特別開心,因此想要拿薪水做一些有意義的事,那時候我做的是認養流浪貓。
我的毛小孩們是兩隻可愛的虎斑貓(文章下面有圖有真相喔!)還記得剛開始認養的時候非常興奮,當時最重要的第一個步驟就是幫可愛的毛小孩取名了!所以我現在想用程式碼紀念一下當初的過程。
為了命名第一隻貓,首先我建立Pet類別,定義first_name方法,且此方法的alias別名是name(新的別名要放在舊的名稱前面):
class Pet
  def first_name
    p "Mac"
  end
  alias name first_name #別名放前面, 舊的方法名放後面, 中間不需要加","逗號
end
Pet.new.name #=> Mac
結果印出:Mac。這是我家寵物的名字~~~(一隻底色為白色的虎斑貓 :3)
如果利用alias_method寫法也是可以的,只要把name方法前面加上:冒號,變成Symbol符號的寫法:
class Pet
  def first_name
    p "Mac"
  end
  alias_method :name, :first_name #別名放前面, 舊的方法名放後面, Symbol之間要加","逗號
end
Pet.new.name #=> Mac
用alias_method的優點是可以作用在繼承的類別。立馬來看看例子:
我家的Mac是一隻調皮的小公貓,有另外一個綽號叫做“麥少爺"(取Mac的諧音~是不是很可愛呀)。
所以我現在寫了一個新的類別Cat繼承自Pet。在Cat類別和Pet類別下都有同名的方法first_name。
class Pet
  def first_name
    p "Mac"
  end
  def self.nickname
    alias_method :name, :first_name
  end
end
class Cat < Pet
  def first_name
    p "麥少爺"
  end
  nickname
end
Cat.new.name #=> "麥少爺"
當我們用Cat.new.name產生一個新物件,程式會走一遍Cat類別,到了nickname這個方法,會跑去繼承父類別Pet的self.nickname方法。
尋找到alias_method之後,呼叫name別名的舊名:first_name,再回來Cat類別跑完執行first_name方法。
此時Mac的花名出現啦!叫做麥少爺。

(喜歡睡在桌機鍵盤上的麥少爺~好療癒!)
如果把上述程式碼轉為alias試試看,幫我的第二隻貓:Dell設定綽號(取諧音叫做戴公子)。
class Pet
  def second_name
    p "Dell"
  end
  def self.nickname
    alias name second_name
  end
end
class Cat < Pet
  def second_name
    p "戴公子"
  end
  nickname
end
Cat.new.name #=> Dell
Cat.new.name 呼叫nickname方法後,並沒有出現別名戴公子,名字仍為Dell。
為啥迷???
這是因為:
alias只會尋找其關鍵字存在的scope。
在本案例裡,是Pet類別裡面的second_name方法。
透過這兩個為小貓取花名的舉例的比較,希望大家能夠更了解alias和alias_method的不同喔!
Ruby比一比:
| alias | alias_method | 
|---|---|
| 屬於在libdoc之下的RDoc裡的關鍵字 | 屬於Module模組方法 | 
| 只會作用在其關鍵字所屬的scope | 可以重新定義方法,較為彈性 | 
alias_method在Ruby on Rails專案很常使用,因為它可以幫我們把功能重複的方法、透過重新改寫方法名的過程,整合到一起。
然而關於alias關鍵字和alias_method哪個比較好用,說實話仍然是見仁見智,詳見我在參考連結的alias vs alias_method與In Defense of Alias,兩位工程師剛好各自擁有相反的觀點。
我在查詢alias/alias_method的過程,以及因為Ruby主題而走過整個鐵人賽的旅程,得到最寶貴的收穫就是:程式碼或舉例,甚至開發任何功能,都會有很多種寫法或解法,但身為工程師最重要的是保有獨立思考的精神(站在世界各地強者的肩膀上、然後寫出自己的風格)、以及享受追求真實(看Ruby文件、掌握原文精髓、並思考這個東西為何最終被創造出來,一定是為了解決某些需要)的過程。
我也計劃著未來熟悉Rails框架後,會繼續進行鐵人賽番外篇 - (續寫30篇Rails面試精選30題),敬請期待!
第15天了,完成一半,剩下一半繼續努力!

(喜歡睡在Mac筆電上的戴公子~~好溫暖)
===
Ref: