2014年10月29日 星期三

[ Ruby Gossip ] Basic : 類別 - 特殊方法定義

Source From Here 
Preface 
在 Ruby 中可以定義特定操作或運算操作的行為,例如 initialize 可以定義建立實例之後初始化的流程,+、-、*、/、==等操作行為也可以使用方法定義,例如自行定義一個有理數類別: 
  1. # encoding: utf-8  
  2. class RationalNumber  
  3.     attr_accessor :numer, :denom  
  4.     def initialize(n, d) # 物件建立之後所要建立的初始化動作  
  5.         @numer = n  
  6.         @denom = d  
  7.     end  
  8.       
  9.     def to_s             # 定義物件的字串描述  
  10.         "#{@numer}/#{@denom}"  
  11.     end  
  12.       
  13.     def +(that)          # 定義 + 運算  
  14.         RationalNumber.new(self.numer * that.denom + that.numer * self.denom,   
  15.                      self.denom * that.denom)  
  16.     end  
  17.       
  18.     def -(that)          # 定義 - 運算  
  19.         RationalNumber.new(self.numer * that.denom - that.numer * self.denom,  
  20.                      self.denom * that.denom)  
  21.     end  
  22.       
  23.     def *(that)          # 定義 * 運算  
  24.         RationalNumber.new(self.numer * that.numer,   
  25.                      self.denom * that.denom)  
  26.     end  
  27.       
  28.     def /(that)          # 定義 / 運算  
  29.         RationalNumber.new(self.numer * that.denom,  
  30.                      self.denom * that.denom)  
  31.     end  
  32.       
  33.     def ==(that)          # 定義 == 運算  
  34.         self.numer * that.denom == that.numer * self.denom  
  35.     end  
  36. end  
  37.   
  38. x = RationalNumber.new(12)  
  39. y = RationalNumber.new(23)  
  40. z = RationalNumber.new(23)  
  41.   
  42. puts x       # 1/2  
  43. puts y       # 2/3  
  44. puts x + y   # 7/6  
  45. puts x - y   # -1/6  
  46. puts x * y   # 2/6  
  47. puts x / y   # 3/6  
  48. puts x == y  # false  
  49. puts y == z  # true  
initialize 定義物件建立後要執行的初始化過程。常見的+、-、*、/、==等操作,可分別由+、-、*、/、==等方法定義,呼叫這些方法時,可以不用.操作,而呼叫方法有Ruby中,括號可以視情況省略,因此看來就像是其它語言中的所謂的運算子。 

特殊方法定義 
self 代表(參考)至訊息接收者,實例方法中撰寫 self 時,self 代表(參考)至實例,也就是運算操作左邊的物件。to_s 用來定義傳回物件描述字串,通常用來描述的字串是對使用者友善的說明文字,有些方法會對物件呼叫 to_s 來取得物件的字串描述,像是 putsprint、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

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...