【Ruby】Method、Block的基本介紹
上週開始在課堂上教學Ruby這個程式語言,自己覺得Ruby的方法跟JavaScript的函式相比之下比較難懂一點,所以這篇來講講Ruby中怎麼樣定義methon(方法),以及在Ruby中常常伴隨方法出現但卻又不太會使用的Block。
方法的定義及呼叫
在Ruby中方法使用def接上方法名稱來定義方法,之後才能夠用定義時賦予的名稱來呼叫方法,方法的名稱與定義區域變數(local variable)時使用的慣例一樣,使用小寫並且依照snake_case的方式來命名。先接觸JavaScript的我常常不自覺使用使用camelCase方式來命名,雖然不會發生錯誤不過共同開發時就會發生撰寫風格不一樣的問題!所以還是多多依照命名習慣來撰寫培養隨時切換語言的能力。除了剛剛提的命名習慣以外,Ruby中方法的名稱還有一個特別之處,就是可以在名稱的最後面加上?,!,=三個特別的符號,分別代表的意思是:
?:此方法只會回傳Boolean。當方法使用二分法在判斷某件事情產生的結果只會是true或false,就會在名稱後面加上?,在閱讀程式碼時可以很快的知道方法執行後的回傳值是什麼。例如:Ruby提供的integer?方法用來判斷數字是不是整數, 或是empty?方法用來判斷是不是empty hash或empty array。arr = [] hash = {} p arr.empty? # ture p hash.empty? #true!:如果在方法的名稱中帶有驚嘆號通常表示此方法會有一些要注意的地方,例如說會改變原本物件本身,例如:陣列中的map方法會產生一個新的陣列,map!方法則會改變原本的陣列並且回傳出來。arr = [1, 2, 3, 4, 5] p double_arr = arr.map { |num| num * 2 } # [2, 4, 6, 8, 10] p arr # [1, 2, 3, 4, 5] p increment_arr = arr.map! { |num| num + 1 } # [2, 3, 4, 5, 6] p arr # [2, 3, 4, 5, 6]另一種例子是在Rails中
find_by方法如果找不到會回傳nil,find_by!找不到則會回傳錯誤為ActiveRecord::RecordNotFound的錯誤訊息。# 用使用者名稱從users table裡找出使用者的資料 p user = User.find_by(username: "Tgo") # 找到 [username: "Tgo", created_at: ...] # 找不到回傳 nil p user = User.find_by!(username: "Ben") # 找到 [username: "Ben", created_at: ...] # 找不到回傳錯誤 ActiveRecord::RecordNotFound (Couldn't find User)=:在Ruby中特別的用法,在方法的名稱後面加上等號=,代表這個方法的行為在做的是assign,會將傳入的參數assign到呼叫方法的物件上,在定義class實體變數的setter時就會用到等號=來定義方法名稱。另外我們在操作array時(arr[0] = 1)或操作hash時(hash["key"] = 1)用來assign新的值到array或hash中,就是array class或hash class提供的[]=方法。
以上的三種符號是一種慣例(Convention),如果不照著做程式碼執行時不會出現錯誤,但會增加之後閱讀程式碼或是要使用這個方法的困擾。
Block的基本介紹
定義好方法後,就可以呼叫定義的方法名稱來執行該方法。在Ruby中有個東西時候會跟使用方法的時候一起出現,就是Block。Block有的時候用起來很像JavaScript的callback function,不過是不一樣的東西。Block的syntax有兩種,一種是do |*args|…end,另一種是{ |*args| ... },它會出現的位置會在呼叫方法的後面,例如:
numbers = [1, 2, 3, 4, 5]
numbers.each do |number|
puts number
end
# 也可以換成 { ... }的形式
numbers.each { |number| puts number }
在JavaScript中可以用forEach()來做到一樣的結果:
const numbers = [1, 2, 3, 4, 5]
numbers.forEach(function (number){
console.log(number)
})
在Block的||之間可以拿到跟callback一樣的參數,在這裡代表的是Array中的每個element。所以我覺得這兩個東西真的長得很像!如果我們想要將Block的用法轉換成callback function一樣的概念,就會還需要兩個東西幫忙-Proc跟Lambda,不過兩個就放到以後的文章在深究吧!
留言