# 對象與方法
先教大家一句咒語: **Ruby中,一切皆對象。**
### 對象(Object)
Ruby是一門解釋執行的動態語言,同時,它也是一門完完全全的面向對象語言。
對象,很好理解,它表示客觀世界中某個具體的個體事物,它是面向對象世界中的基本單元。它是某一個類的具體實例, 一個對象,應該包含其唯一的標識符,屬性(attributes)以及方法(Methods)。
屬性(attributes)即為一個對象的特點,用于描述這個對象的個性,而方法(Methods),則為這個對象能夠提供的服務,及其行為。
舉個例子:
~~~
人類,是一個類別。 人類中某個個體,為張三。 他是男性,中國人,黃色人種。他會做飯,是大廚,他唱歌也很好聽。
~~~
那么用Ruby代碼來描述的話,應該是這樣的:
~~~
# 人類
Class People
attr_accessor :name, :gender, :race, :nationality
def initialize(name='', gender='', race='', nationality='')
@name = name
@gender = gender
@race = race
@nationality = nationality
end
end
# 上帝造了張三
person = People.new
person.name = "張三"
person.gender = '男'
person.race = 'yellow'
person.nationality = 'China'
def person.chef
puts "good"
end
def person.sing
puts "good"
end
~~~
上面的代碼, Class即為創建一個類,比如People, 是指人類。
attr_accessor , 聲明了People類的屬性,比如,人類是有名字(name)、有性別(gender)、有種族(race)、有國籍(nationality)。
我們可以使用new方法,來使用People類來造一個對象,也就是一個人, 我們用person表示。
~~~
person = People.new
~~~
我們使用「點」來指定person的name,并賦與其值。
~~~
person.name = '張三'
~~~
而實際上,attr_accessor,是動態生成了類似下面的方法:
~~~
class People
# ...
def name
@name
end
def name=(name)
@name=name
end
# 其他屬性方法類似
end
~~~
def,是聲明一個方法, 為對象創建一個行為。 比如上面的person.name = '張三', 就是允許給person起名字。
而像下面這樣的代碼:
~~~
def person.chef
puts "good"
end
~~~
當執行person.chef的時候,會輸出‘good’。
則是給「張三」這個個體創建一個頭銜,廚師(chef),代表他會做飯。這個會做飯的技能, 只是他這一個個體特有的,你可以再創建一個人「李四」來嘗試一下:
~~~
other_person = People.new
other_person.name = '李四'
~~~
你可以讓「李四」來調用chef方法, 則會報錯。
### 消息傳遞
我們上面的代碼中: person.chef , 我們叫它方法調用。
而Ruby更愿意把它稱作,消息傳遞。
person,是一個對象, 是一個消息接收者。
chef,是一個消息。
通過一個「點」, 我們把chef這個消息傳遞給person, 假如person可以響應這個消息,那么它就會響應結果,否則,則報錯無法響應。
消息傳遞,是對象之間傳遞信息的唯一手段。
還記得我們的咒語嗎? Ruby中一切皆對象。我們使用Ruby,就是使用對象, 想讓對象為你工作,那么你就得給他傳遞消息。
包括要設置對象自己的屬性,也是使用消息傳遞的方式,這也是上面代碼中為什么要有「attr_accessor」方法。
**另一句咒語: Ruby中一切都是消息傳遞(「方法調用」)**
所以,Ruby里各種內建數據結構,比如字符串、數組、Hash等,也內置了一些方法,你也可以用同樣的方式來調用。可以去[ruby-doc.org](http://ruby-doc.org)來查找這些方法。
### Chef中的抽象
回頭看我們的自動化管理工具Chef中的一些概念,我們更容易理解這種對象與消息的思想。
比如,在OpsCode給出的apache Cookbook中,設置attributes的一段代碼:
~~~
node.default["apache"]["dir"] = "/etc/apache2"
node.default["apache"]["listen_ports"] = [ "80","443" ]
~~~
node, 即為一個對象,Chef中把具體要配置管理的服務器,抽象為一個類Node,而上面代碼中的node,即為那個具體的要使用Chef進行配置管理的服務器或者是其他Chef可配置管理的任何東西。
### 思考:
結合本節的內容,來思考下面這段代碼的意思?
~~~
node.default['apache']['dir'] = '/etc/apache2'
~~~
- 序
- Chapter 1: 初識Chef
- 一些背景
- Chef vs Puppet
- Chapter 2: Chef應用
- Chef架構
- Chef能做什么
- Chef組件
- Chef環境安裝
- chef-server
- opscode-chef
- chef-solo
- Chef實戰
- 實戰前的必修理論
- 使用Chef
- Chapter 3: Ruby基礎
- 對象與方法
- 標識符
- 類與模塊
- 數據類型
- 真與假
- 控制語句
- 代碼塊
- Chapter 4: Chef源碼架構
- Rubygems與gem
- bundler
- Chef源碼組織
- Chapter 5: Rails基礎
- Rails是什么
- MVC架構
- Restful
- Rails組成與項目結構
- Chapter 6: Chef Server WebUI
- Chef Server Webui組織結構
- Chef Rest API
- 參考