轉自:http://galeki.is-programmer.com/show/183.html
如同其他的OO語言一樣,在ruby中,通過給對象發送訊息,來完成對象的功能,比如 str.upcase ,就是給str發送upcase的訊息,點操作符(.),就是用來給對象發送訊息的,str接受到訊息,然後執行與訊息對應的功能。
但是,某些時候,我們並不知道對象能響應哪些訊息,比如下面的代碼就會產生錯誤:
- > obj = Object.new
- > obj.talk
- undefined method 'talk' for #<Object:0x12345678> (NoMethodError)
因為obj對象沒法響應talk這個訊息,如果使用 respond_to? 這個方法,就可以實現判斷對象能否響應給定的訊息了:
- obj = Object.new
- if obj.respond_to?("talk")
- obj.talk
- else
- puts "Sorry, object can't talk!"
- end
這樣即使obj不能響應talk,也不會使代碼產生錯誤退出,我們也可以應用 respond_to? 方法,根據對象的屬性,在程式運行時靈活的控制。
與 respond_to? 相對應,send 方法和點操作符一樣,用來給對象發送訊息,比如文章開始的 str.upcase ,用 send 可以寫成 str.send("upcase"),它們實現的功能是完全相同的,那麼為什麼還要用send呢?
這是因為,send 發送的訊息,在程式運行時是可變的,我們可以根據不同的輸入,動態向對象發送不同的訊息。
比如一個圖書管理系統,每本書都有諸如作者、出版社、日期、價錢這些,我們要根據使用者的輸入查詢某本書的屬性,如果不用send,我們要對程式的輸入做一個一個的測試:
- print "Search for: "
- request = gets.chomp
- if request == "writer"
- puts book.writer
- elsif request == "press"
- puts book.press
- elseif request == "date"
- puts book.date
- ......
如果用send方法的話,就簡單多了:
- request = gets.chomp
- if book.respond_to?(request)
- puts book.send(request)
- else
- puts "Input error"
- end
這樣不用在逐個對使用者的輸入進行測試,只要查詢對象能否相應這個訊息,再用send將輸入直接發送給對象即可。
通過 respond_to? 和 send 這兩個方法,我們可以構造更靈活和穩定的程式。