今天有兩個小測驗在後面,今天才知道丟引數的規則,所以丟引數測得很High,有興趣的朋友也可以想想看方法是怎麼傳遞引數的(凌晨不睡在測Ruby方法引數的傳遞方式,我應該可以當工程師了XD)
※ 方法的引數
在定義方法時,我們會在方法名稱後面的圓括號加入引數,引數所接收到的內容可以被送進該方法中,我們今天要來認識引數的規則。
1. 設定引數的預設值
def point(x=3,y=4,z=5)
"(#{x},#{y},#{z})"
end
point
=> "(3,4,5)"
point(7,8,9)
=> "(7,8,9)"
設定引數的預設值很簡單,就是在定義方法時,引數的後面接上等於,再接上預設值即可。但要注意!如果上面的範例沒有設x,y,z的預設值,那直接輸入point的結果會噴錯:
def point(x,y,z)
"(#{x},#{y},#{z})"
end
point
ArgumentError: wrong number of arguments (0 for 3)
point(5,6,7)
=> "(5,6,7)"
因為沒有預設值,所以在呼叫函數的時候要自己在後面加入引數值才可以正常運作。
『引數之中有些有預設值有些沒有,該怎麼辦?』
要記得以下規則:
(1) 有預設值的引數一定要『相鄰』!下方為錯誤寫法:
def point(x=3,y,z=5)
"(#{x},#{y},#{z})"
end
一定要讓有預設值的引數接在一起,所以要改成:
def point(x=3,y=5,z) 或 def point(x,y=3,z=5)
(2) 在呼叫方法時,給定的引數會由左至右填入,例如:
def point(x,y=3,z=5)
"(#{x},#{y},#{z})"
end
point(2)
=> "(2,3,5)" # 只給一個,自動從最左邊的洞填入,因此動到x,其它用預設值。
point(1,7)
=> "(1,7,5)" # 給了兩個,從最左邊開始往右邊填,動到x,y,剩下的用預設值。
或是這樣
def point(x=3,y=5,z) # 注意本次給預設值的順序跟上面的不一樣。
"(#{x},#{y},#{z})"
end
point(9)
=> "(3,5,9)" # 只給一個,結果自動先去找沒有預設值的填入!!!!
point(10,88) # 這個結果很特別,多多注意!!!!
=> "(10,5,88)"
# 給了兩個,由左而右,先填第一個有預設值的,
# 剩下一個則判斷,如果剛好有一個沒設預設值,就給它!
point(7,49,22)
=> "(7,49,22)" # 給三個不用說,就是由左至右乖乖填入。
def test(a,b=2,c=3,d=4,e,f) # 注意有給預設值的引數,只要有相鄰即可!
"#{a},#{b},#{c},#{d},#{e},#{f}"
end
test(55,66,77) = ?
test(55,66,77,88) = ?
test(55,66,77,88,99) = ?
答案明天揭曉(大誤),好啦請拉到這頁最下方就可以看到XD
2. 不定長度的引數串列與陣列
有時候我們希望方法可以接受任意數目的引數,此時我們會替引數前綴一個『*』,此時當引數傳到該位置時,傳的其實是一個陣列,例如:
def idol(name,*skill)
puts "我是#{name},我會#{skill}"
end
idol("Jolin","sing","write","dance")
=> 我是Jolin,我會["sing", "write", "dance"]
可以看到上方的例子中,我們傳入了4個引數,第1個是name的引數,第2、3、4個都會被傳入skill中變成陣列!
這個『*』還不只可以這樣用,我們甚至可以直接傳遞一個陣列給idol方法用,只要我們這樣寫:
super_star = ["Matz","ruby1.0","ruby2.0","ruby3.0","ruby4ever"]
idol(*super_star)
=> 我是Matz,我會["ruby1.0", "ruby2.0", "ruby3.0", "ruby4ever"]
注意到,『*』可以自動幫我們展開這個陣列,套入idol方法時,就會丟入相對應的位置!超酷!
不過如果剛剛上面沒有加上『*』,會發生什麼事呢?
idol(super_star)
=> 我是["Matz", "ruby1.0", "ruby2.0", "ruby3.0", "ruby4ever"],我會[]
他直接把整個陣列都丟入第一個引數的位置了,後面的當做沒傳東西所以變成空陣列!
下方我們來看清楚引數個數丟到方法裡的規則!
def test(a,*b,c)
puts "a=#{a}"
puts "b=#{b}"
puts "c=#{c}"
end
test(1,2)
a=1
b=[]
c=2 # 因為b加上前綴的*,所以它可以是空陣列。
test(1,2,3)
a=1
b=[2]
c=3
test(1,2,3,4)
a=1
b=[2, 3]
c=4
test(1,2,3,4,5)
a=1
b=[2, 3, 4]
c=5
啊,引數還沒說完,不過接下來會講到蠻大的重點,所以我們先把今天所說的內容給弄清楚吧!來個終極大考驗好了,預設值、『*』、引數個數差異大・亂・鬥!!
def final_test(a,b=2,c=3,*d,e)
puts "a=#{a}"
puts "b=#{b}"
puts "c=#{c}"
puts "d=#{d}"
puts "e=#{e}"
end
final_test(10,11) = ?
final_test(10,11,12) = ?
final_test(10,11,12,13) = ?
final_test(10,11,12,13,14) = ?
final_test(10,11,12,13,14,15) = ?
=================================================
27天!!!
Life is simple. Are you happy? Yes? Keep going. No? Change something.
阿說好要公佈答案的XD白天再公佈在留言好了XD囧會不會結果都沒有人試XD沒關係我自己覺得這裡很好玩XDD現在是凌晨四點多,看Ruby的書越看越high,好可怕XD
[終極大考驗答案XD]
final_test(10,11)
a=10
b=2
c=3
d=[]
e=11
final_test(10,11,12)
a=10
b=11
c=3
d=[]
e=12
final_test(10,11,12,13)
a=10
b=11
c=12
d=[]
e=13
final_test(10,11,12,13,14)
a=10
b=11
c=12
d=[13]
e=14
final_test(10,11,12,13,14,15)
a=10
b=11
c=12
d=[13, 14]
e=15
哈哈哈答對了嗎?老實說我自己在final_test錯了,筆記一下:原來有加*的都是最後才丟引數!