Preface
在 Ruby 中可以定義特定操作或運算操作的行為,例如 initialize 可以定義建立實例之後初始化的流程,+、-、*、/、==等操作行為也可以使用方法定義,例如自行定義一個有理數類別:
- # encoding: utf-8
- class RationalNumber
- attr_accessor :numer, :denom
- def initialize(n, d) # 物件建立之後所要建立的初始化動作
- @numer = n
- @denom = d
- end
- def to_s # 定義物件的字串描述
- "#{@numer}/#{@denom}"
- end
- def +(that) # 定義 + 運算
- RationalNumber.new(self.numer * that.denom + that.numer * self.denom,
- self.denom * that.denom)
- end
- def -(that) # 定義 - 運算
- RationalNumber.new(self.numer * that.denom - that.numer * self.denom,
- self.denom * that.denom)
- end
- def *(that) # 定義 * 運算
- RationalNumber.new(self.numer * that.numer,
- self.denom * that.denom)
- end
- def /(that) # 定義 / 運算
- RationalNumber.new(self.numer * that.denom,
- self.denom * that.denom)
- end
- def ==(that) # 定義 == 運算
- self.numer * that.denom == that.numer * self.denom
- end
- end
- x = RationalNumber.new(1, 2)
- y = RationalNumber.new(2, 3)
- z = RationalNumber.new(2, 3)
- puts x # 1/2
- puts y # 2/3
- puts x + y # 7/6
- puts x - y # -1/6
- puts x * y # 2/6
- puts x / y # 3/6
- puts x == y # false
- puts y == z # true
特殊方法定義
self 代表(參考)至訊息接收者,實例方法中撰寫 self 時,self 代表(參考)至實例,也就是運算操作左邊的物件。to_s 用來定義傳回物件描述字串,通常用來描述的字串是對使用者友善的說明文字,有些方法會對物件呼叫 to_s 來取得物件的字串描述,像是 puts、print、p 等方法(irb 中也是使用 to_s 取得字串描述),如果雙引號字串中包括 \ 忽略(Escape)字元,puts 與 print 會忽略下一個字元,而 p 則不會忽略直接輸出。
與 to_s 類似的是 to_str 方法,在運算操作時(例如串接字串)如果需要從物件取得字串,若沒有指定方法操作,則會呼叫 to_str 而不是 to_s。例如:
上例中同時定義了 to_s 與 to_str,可以清楚看到 irb 中使用的是 to_s,而串接字串時會使用 to_str。
在某些操作場合,需要從物件取得陣列(例如串接陣列),若沒有指定方法操作,則通常預設會呼叫 to_ary。例如:
實例變數的設值方法,可以使用 name= 來定義,其中 name 為實例變數名稱。類似地,[] 運算操作的行為,可用 [] 與 []= 方法來定義。例如:
單元運算的方法名稱比較特殊,為運算字元後加上 @。例如:
要注意,= 不能 使用方法定義,所以其它如 +=、-=... 等也不能使用方法定義,&& 與 || 具有捷徑運算,你也無法用方法定義,因此 & &= 與 ||= 也無法使用方法定義。可以使用方法定義的運算操作有 +、-、*、/、%、[]、[]=、<<、>>、==、 >、<、>=、<=、===、&、|、^、~、!。
在 迭代器與程式區塊 中談過,可以為物件定義迭代器,如果某個物件上擁有 each 迭代方法,也就可以使用 for 語法。例如陣列就擁有 each 方法,可以使用 each 方法迭代元素,也可以使用 for 迭代元素. 一個簡單範例如下:
Supplement
* Ruby tutorialspoint - Ruby Operators
沒有留言:
張貼留言