接續昨天的話題,昨天我們有提到,定義一個方法時要注意:
1. 方法的名稱有規定寫法,待下方再做解釋
2. 圓括號通常可省略,但也有不可省略之時,也是待下方再做解釋
3. 圓括號中的參數,可直接作為方法程式碼中的變數(參數所提供的值,為調用方法時所給的引數)
好的,今天來說說方法的名稱與圓括號的規定!
※ 方法的名稱
1. 慣例以小寫字母開頭(雖然大寫可以,但這會讓它看起來很像常數)
2. 方法名稱不只一個單字時,通常以底線符號分隔,例如:who_am_i
3. 方法名稱可以用一個等號、一個問號或一個驚嘆號結尾,例如:age=、include?、sort!
3-1. 一個等號:就是之前在類別時有提到的setter做法 >> Ruby女孩(19)
3-2. 一個問號:問號就很像一個問題,任何方法名稱只要以問號結尾,都會回傳一個值來回答問問題(通常是true或false)。我們之前常看到is_a?這個方法就是一個例子>>
String.is_a? Object
=> true
問題:String是一個物件嗎?
答案:是的!
3-3. 一個驚嘆號:驚嘆號有警示的意味存在,使用的時候要很小心,一般沒有加驚嘆號的時候,會做一個副本來儲存變動後的內容;但若是有加驚嘆號的話,他會直接在原物件上修改內容。舉例來說,陣列都會有一個sort的方法,作為排序之用,以下比較sort與sort!的差異:
a = [3,1,2]
a.object_id
=> 70243998348660
a.sort.object_id
=> 70244014688220 #用另一個副本空間來做sort,不會改到原本的物件
a.sort!.object_id
=> 70243998348660 #在原本a所指到的物件上做sort,所以會修改到原本的物件
所以如果這樣看:
a = [3,1,2]
a.sort
=> [1, 2, 3]
a
=> [3, 1, 2] #原本a所指到的物件並未修改
a.sort!
=> [1, 2, 3]
a
=> [1, 2, 3] #原本a所指到的物件被改掉了!
※ 運算符方法
Ruby中有很多運算符,例如+、*...這些其實都是方法,我們平常看到的1+2其實是因為1有一個方法叫做+,它也可以這樣寫:
1.+(2)
等同於
1.+2
等同於
1+2
1+2當然是最簡便的寫法,不過也許很多人用太習慣了,會不知道原來這也是利用方法的定義來做的,我們甚至可以惡搞改掉+的方法定義(參考自Ruby也可以這樣寫):
class Fixnum
alias :fake_plus :+ #alias用法隨即介紹,請往下看
def +(num)
self.fake_plus(num).-(num)
end
end
Fixnum本身就有+這個方法,我們偷偷把+的定義改成+完再-,結果:
1+2
=> 1
40+88
=> 40
不知道的人可能以為自己的加法壞掉了,怎麼加都沒變,原來是+的定義被改掉了XD
※ 方法的別名
Ruby中很多方法都有別名,這是一個非常人性化的做法,常常可以讓整串code更符合語意,例如以前曾介紹過.include?、.member?、.cover?這三個方法就是同義的方法,都在看一個物件有沒有被包含:
rubyist = ["Annie","Linda","Ironman"]
rubyist.member? "Annie"
=> true
high_score = (82..98)
high_score.cover? 88
=> true
上面的方法定義相同,但會有比較自然語意的方法!
除了語意之外,還有一種比較實際的理由,就是可以用alias的方式來幫擴充或修改既有的方法!
alias寫法:『alias 別名 原名』,例如剛剛提到的:
alias :fake_plus :+
:fake_plus是我幫他取的別名
:+是原本的名字
剛剛前面的+是一個例子,我們再看一個例子:
class Test
def hello
"我是舊方法"
end
alias old_method hello
def hello
"我來擴充新東西了>>" + old_method
end
end
步驟一:在類別中定義舊方法
步驟二:幫舊方法取別名
步驟三:用舊方法的名字定義新內容,還可以用舊方法的別名呼叫它!
執行看看:
a = Test.new
=> #<Test:0x007fa873806ee8>
a.hello
=> "我來擴充新東西了>>我是舊方法"
※ 方法與圓括號
方法後面跟的圓括號是可以省略的,除了少數特例之外!
puts "Hello" 其實是 puts ("Hello") 的省略版本。
3.between? 1,5 與 3.between?(1.5) 也是一樣的!
在方法定義的時候,也可以省略:
def sum(x,y)
x+y
end
def sum x,y
x+y
end
上面這兩個也是一樣的!
好的,那到底什麼時候不能省略呢?
例如函數之間巢狀使用的時候:
f(g(h(x,y)))
f(g(x),y)
這不加括號應該很恐怖吧...
f g h x,y
誰看得懂==
還有一些含糊不清的寫法,都建議主動加上括號:
def pp(num)
num*num
end
pp(2+2)*2
=> 32
pp (2+2)*2
=> 64
可以看到下面兩個呼叫pp方法的寫法只差有沒有空格,可是卻有不同的結果,因為它得判斷num到底是引入哪個參數,是(2+2),還是(2+2)*2,所以為了寫清楚,可以改成:
pp((2+2)*2)
這樣就比較不會搞錯!
至於引數的內容也有很多可以講呢!有待明日分曉XD
=================================================
26天了!
“The problem is not the problem. The problem is your attitude about the problem.”
1.()<-這個叫小括號,不叫圓括號
2.你認為含糊不清楚的東西,跟程式語言的結合律有關,請先理解,再來說含糊不清,相信真正的資深工程師會感激你
謝謝你的提醒喔:)
囧"看來寫文章也得向Ruby精神學習呢QQ要人性化之外...可讀性也很重要Orz
(ps.抱歉,我用鐵人賽的版面回完才想到那個可能不會通知你我有回,所以到這裡再回一次)
@dojumi 謝謝你的提醒喔:)