要一个真正的问候者(greeter),他能记住你的名字、问候你、总是尊重地向 你示好?那么这就最好建立一个“Greeter”类:
在上面的类代码中定义了一个称为 Greeter 的类和一些类方法, 其中出现了一些新的“关键 词”:请注意“@name”,它是类的实例变量,并对类中的所有方法(say_hi 和 say_bye 方法)都 有效。
如 何 让 Greeter 类 发 挥 作 用 ? 现 在 让 我 们 来 建 立 一 个 Greeter 对 象 并 使 用 它 !
Greeter 类的实例对象 g 被建立后,它便接受了 name 参数(值为 Pat)。那么我们能直 接访问 name 吗?
看看上面的编译错误来看,这样直接访问 name 是行不通的。
窥视对象的内部
对象中的实例变量总是隐藏于其中,但也并非毫无踪迹可寻,通过审查(inspect)对象便 会见到它们。当然还有其它的访问方法,但是 Ruby 采用了良好的面向对象的方式来保持数据的
隐藏性。
喔!这么多方法,可是我们只定义了两个方法呀?其它的方法又出自何处?不要担心,ins tance_methods 方法列出了 Greeter 对象的所有方法,其中包括父类中定义的方法。如果我们 只想对 Greeter 类的方法进行列表的话, 那么把 false 作为参数调用 instance_methods 方法即 可。false 意味着我们不需要父类定义的方法。
哈 哈, 这才 是我 们想要 的。 下面 让我 们看 看 Greeter 对象能 回应 哪些方 法 :
它知道 say_hi、to_s(此方法
将对象转换为字符串,是任何对象都必备的默认方法,很想
Java 中的 toString 方法),但它不知道 name。
随时修改类定义
如何才能查看或者修改 name 呢?Ruby 提供了访问对象变量的简单方法:
在 Ruby 语言中,你能够多次打开某个类并修改它。而修改所带来的变化将应用在此后建 立的任何新对象中、甚至现存的此类对象中。下面让我们建立一个新对象并访问它的@name 属 性。
我们通过使用 attr_accessor 定义了两个方法: “.name”用来获取 name 属性值; “.name=”用来设置 namee 属性值。 这很类似在 Java 类中访问被 Public 修饰的成员变量。
向每个人问候 , MegaGreeter 不会漏掉一个人
Greeter 并不完美,因为它只能一次服务一个人。所以我们在这里
设计一个能够一次向全
世界、世界上每个人或者在名单中的人发送问候的 MegaGreeter 类。在这里,我们将放弃从前 的 IRB 交互模式,转而改为编写 Ruby 程序文件。
退出 IRB 的方法:输入“quit”、“exit”或者按下 Control+D 的组合键。
保存上面的代码到名为“ri20min.rb”的文件中,并使用“ruby ri20min.rb”的命令执行它。 程序输出如下:
下面我们将深入了解一下上面的代码。
请注意上面代码中的起始行,它以#开头。在 Ruby 语言中,任何以#开头的行都被视为注 释,并被解释
程序忽略。
我们的 say_hi 方法已经发生了变化:
它查找@names 参数并按照其参数值作出决定: 如果参数值为 nil,它将打印三个圆点。 那么@names.respond_to?("each")表示什么?
循环——也叫迭代 也叫迭代 循环
如果@names 对象具有 each 方法,那么它是可以被迭代的,进而可以对其进行迭代,从 而问候列表中每个人。如果@names 不具备 each 方法,则将它自动转换为字符串,并执行默认 的问候。
each 是一种方法,它接受一个代码块(block of code),然后针对列表中的每个成员执 行这个代码块,而在 do 和 end 之间的部分便是这个非常类似匿名函数的代码块。在管道符之间 的变量是代码块的参数 name,它作为代码块参数被绑定为列表成员,而代码块 puts "Hello # {name}!"将使用这个参数进行输出。
大多数其它的编程语言使用循环遍历列表,下面是 C 语言的循环示例:
上面的代码显然可以
工作,但它不够“优雅”!你不得不用 i 这个多余的循环变量,还需要指 出
列表的长度,然后再解释如何遍历列表。
Ruby 的迭代方式则更加优雅,所有的内部管理细节都隐藏在 e