🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 对象与方法 先教大家一句咒语: **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' ~~~