一、向對象顯示的發送消息
我們可以向對象直接發送消息:
Ruby代碼
代碼如下:
class HelloWorld
def say(name)
print "Hello, ", name
end
end
hw = HelloWorld.new
hw.send(:say,"world")
我們通常使用hw.say("world"),但send可以對private的方法起作用。
不光如此send可以使程序更加動態,下面我們看看一個例子:
我們定義了一個類Person,我們希望一個包含Person對象的數組能夠按
照Person的任意成員數據來排序:
Ruby代碼
代碼如下:
class Person
attr_reader :name,:age,:height
def initialize(name,age,height)
@name,@age,@height = name,age,height
end
def inspect
"#@name #@age #@height"
end
end
在ruby中任何一個類都可以隨時打開的,這樣可以寫出像2.days_ago這樣優美
的code,我們打開Array,并定義一個sort_by方法:
Ruby代碼
class Array
def sort_by(sysm)
self.sort{|x,y| x.send(sym) <=> y.send(sym)}
end
end
我們看看運行結果:
Ruby代碼
people = []
people << Person.new("Hansel",35,69)
people << Person.new("Gretel",32,64)
people << Person.new("Ted",36,68)
people << Person.new("Alice", 33, 63)
p1 = people.sort_by(:name)
p2 = people.sort_by(:age)
p3 = people.sort_by(:height)
p p1 # [Alice 33 63, Gretel 32 64, Hansel 35 69, Ted 36 68]
p p2 # [Gretel 32 64, Alice 33 63, Hansel 35 69, Ted 36 68]
p p3 # [Alice 33 63, Gretel 32 64, Ted 36 68, Hansel 35 69]
這個結果是如何得到的呢?
其實除了send外還有一個地方應該注意attr_reader,attr_reader相當于定義了name,
age,heigh三個方法,而Array里的sort方法只需要提供一個比較方法:
x.send(sym) <=> y.send(sym) 通過send得到person的屬性值,然后在使用<=>比較
二、定制一個object
<< object
ruby不僅可以打開一個類,而且可以打開一個對象,給這個對象添加或定制功能,而不影響
其他對象:
Ruby代碼
a = "hello"
b = "goodbye"
def b.upcase
gsub(/(.)(.)/)($1.upcase + $2)
end
puts a.upcase #HELLO
puts b.upcase #GoOdBye
我們發現b.upcase方法被定制成我們自己的了
如果想給一個對象添加或定制多個功能,我們不想多個def b.method1 def b.method2這么做
我們可以有更模塊化的方式:
Ruby代碼
b = "goodbye"
class << b
def upcase # create single method
gsub(/(.)(.)/) { $1.upcase + $2 }
end
def upcase!
gsub!(/(.)(.)/) { $1.upcase + $2 }
end
end
puts b.upcase # GoOdBye
puts b # goodbye
b.upcase!
puts b # GoOdBye
這個class被叫做singleton class,因為這個class是針對b這個對象的。
和設計模式singleton object類似,只會發生一次的東東我們叫singleton.
<< self 給你定義的class添加行為
Ruby代碼
class TheClass
class << self