接續昨天的話題,昨天我們有提到,定義一個方法時要注意:
好的,今天來說說方法的名稱與( )的規定!
age=
、include?
、sort!
- 一個等號:就是之前在類別時有提到的setter做法 » Ruby女孩(19)
- 一個問號:問號就很像一個問題,任何方法名稱只要以問號結尾,都會回傳一個值來回答問問題(通常是true或false)。我們之前常看到is_a?
這個方法就是一個例子(範例1)
- 一個驚嘆號:驚嘆號有警示的意味存在,使用的時候要很小心,一般沒有加驚嘆號的時候,會做一個副本來儲存變動後的內容;但若是有加驚嘆號的話,他會直接在原物件上修改內容。舉例來說,陣列都會有一個sort
的方法,作為排序之用,以下比較sort
與sort!
的差異(範例2a,2b)#範例1
String.is_a? Object
=> true
問題:String是一個物件嗎? 答案:是的!
#範例2a
a = [3,1,2]
a.object_id
=> 70243998348660
a.sort.object_id
=> 70244014688220 #用另一個副本空間來做sort,不會改到原本的物件
a.sort!.object_id
=> 70243998348660 #在原本a所指到的物件上做sort,所以會修改到原本的物件
所以如果這樣看:
#範例2b
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.”