<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-28827285</id><updated>2009-02-22T00:46:18.182+09:00</updated><title type='text'>nucleus-&gt;G&lt;-</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>22</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-28827285.post-115278462587352645</id><published>2006-07-13T18:56:00.000+09:00</published><updated>2006-07-13T18:57:06.023+09:00</updated><title type='text'>第八章 异常，catch和throw</title><content type='html'>&lt;p class="MsoNormal" style="text-indent: 21pt;" align="center"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;第八章  异常，catch和throw&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;迄今为止我们已在&lt;/span&gt;&lt;span lang="EN-US"&gt;Pleasantville&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内开发了代码，这是个没有错误的地方。每个库都可成功调用，用户从不会输入错误数据，资源是丰富和廉价的。当然这并不真实。欢迎回到现实中来。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在现实生活中，会有错误发生。好的程序&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和程序员&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;可预见到错误并优雅地安排对错误的处理。但是这并不总是像说起来这么容易。通常，用于侦测错误的代码并不真的知道它们在做什么。例如，在有些情况下，试图打开一个不存在文件的做法可能是合理的，而这在其它时候可是个致命错误。你的文件处理模块用来做什么？&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;传统方式是使用返回代码。&lt;/span&gt;&lt;span lang="EN-US"&gt;open&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法返回一些特定值来说明它失败了。然后这个值在调用例程层中向外传播，直到有人出于责任而捕获它。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这个方式的问题是管理这么多错误代码可能是件痛苦的事。如果一个函数调用&lt;/span&gt;&lt;span lang="EN-US"&gt;open&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，然后是&lt;/span&gt;&lt;span lang="EN-US"&gt;read&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，最后是&lt;/span&gt;&lt;span lang="EN-US"&gt;close&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，而这每一步都可能返回一个错误代码，这个函数如何能够区别调用返回的这些错误代码。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;在很大范围内用异常来解决这个问题。异常让你包装有关的错误信息到一个对象内。然后这个异常对象被自动从调用堆栈向外传播，直到运行时系统找到，明确地声明了它知道如何处理这个异常类型的代码。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;Exception &lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;类&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;包含有关一个异常信息的包是个&lt;/span&gt;&lt;span lang="EN-US"&gt;Exception&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类或它的子类的对象。&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;预定义了一个简洁的异常层次，像下一页中表&lt;/span&gt;&lt;span lang="EN-US"&gt;8.1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;显示的。稍后我们会看到，用这个层次处理异常相当地容易。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;当你需要引发一个异常时，你可使用内建的&lt;/span&gt;&lt;span lang="EN-US"&gt;Exception&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类，或你自己创建的异常类中的一个。如果你自己创建，你可能需要让它成为&lt;/span&gt;&lt;span lang="EN-US"&gt;StandardError&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或它的子类的一个子类。如果你不这么做，你的异常在缺省情况下不会被捕获。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;每个异常都有相关的消息字符串一个堆栈轨迹。如果你定义了自己的异常，你可以添加额外的信息。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;处理异常&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;我们自动点唱机使用一个&lt;/span&gt;&lt;span lang="EN-US"&gt;TCP&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;套接字在互联网上下载歌曲。基本代码很简单&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;假设&lt;/span&gt;&lt;span lang="EN-US"&gt;filename&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;socket&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;已经设置完了&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;op_file = File.open(opfile_name, "w")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;while data = socket.read(512)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;op_file.write(data)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果我们在下载到一半时出现了一个致命的错误，这会怎样&lt;/span&gt;&lt;span lang="EN-US"&gt;?&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;当然，我们不会将一个完整的歌曲存储到歌曲列表中。&lt;/span&gt;&lt;span lang="EN-US"&gt; “I Did It My *click*.”&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;让我们添加一些异常处理代码，看看这会有什么帮助。为了对异常进行处理，我们封装引起异常的代码在一个&lt;/span&gt;&lt;span lang="EN-US"&gt;begin/end&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;块中，并且使用一或多个&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句来告诉&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;我们想处理的异常类型。在这个特定的例子中，我们只感兴趣&lt;/span&gt;&lt;span lang="EN-US"&gt;SystemCallError&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;异常&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;当然也包括它的子类&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，所以它会出现在&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;行中。在错误处理块内，我们报告错误，关闭和删除输出文件，然后重新引发这个异常。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;op_file = File.open(opfile_name, "w")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;begin&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# Exceptions raised by this code will&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# be caught by the following rescue clause&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;while data = socket.read(512)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 105pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;op_file.write(data)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;rescue SystemCallError&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;$stderr.print "IO failed: " + $!&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;op_file.close&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;File.delete(opfile_name)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;当一个异常出现时，它有单独的异常处理，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;放置相关的异常对象的引用在全局变量&lt;/span&gt;&lt;span lang="EN-US"&gt;$!&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;异常指针令人惊异地会镜像我们可能引起错误的任何代码&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。在前面例子中，我们使用&lt;/span&gt;&lt;span lang="EN-US"&gt;$!&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变量来格式化我们的错误消息。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在关闭和删除文件后，我们调用无参数的&lt;/span&gt;&lt;span lang="EN-US"&gt;raise&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，它重新引发&lt;/span&gt;&lt;span lang="EN-US"&gt;$!&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内的异常。这是个很有用的技术，它允许你编写这样的代码，过滤异常，传递你没有处理的那些异常到上层。它几乎就像是实现的一个对错误处理的继承层次。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;你可在一个&lt;/span&gt;&lt;span lang="EN-US"&gt;begin&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;块内使用多个&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句，而每个&lt;/span&gt;&lt;span lang="EN-US"&gt;resuce&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句可以指定多个要捕获的异常。在每个&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句末端时你可以给出一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的局部变量来接收匹配的异常。很多人认为在下述位置上使用&lt;/span&gt;&lt;span lang="EN-US"&gt;$!&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;更易于阅读。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;begin&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;eval string&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;rescue SyntaxError, NameError =&gt; boom&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print "String doesn't compile: " + boom&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;rescue StandardError =&gt; bang&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print "Error running script: " + bang&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;shapetype id="_x0000_t75" coordsize="21600,21600" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"&gt;&lt;stroke joinstyle="miter"&gt;&lt;formulas&gt;&lt;f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;f eqn="sum @0 1 0"&gt;&lt;f eqn="sum 0 0 @1"&gt;&lt;f eqn="prod @2 1 2"&gt;&lt;f eqn="prod @3 21600 pixelWidth"&gt;&lt;f eqn="prod @3 21600 pixelHeight"&gt;&lt;f eqn="sum @0 0 1"&gt;&lt;f eqn="prod @6 1 2"&gt;&lt;f eqn="prod @7 21600 pixelWidth"&gt;&lt;f eqn="sum @8 21600 0"&gt;&lt;f eqn="prod @7 21600 pixelHeight"&gt;&lt;f eqn="sum @10 21600 0"&gt;&lt;/f&gt;&lt;path gradientshapeok="t"&gt;&lt;lock aspectratio="t"&gt;&lt;/lock&gt;&lt;shape id="_x0000_i1025" style="" type="#_x0000_t75"&gt;&lt;imagedata src="http:///C:DOCUME%7E1ADMINI%7E1LOCALS%7E1Tempmsohtml11clip_image001.emz"&gt;&lt;/imagedata&gt;&lt;/shape&gt;&lt;/path&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/formulas&gt;&lt;/stroke&gt;&lt;/shapetype&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是如何确定哪个&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句被执行的？它将它们处理成类似于使用&lt;/span&gt;&lt;span lang="EN-US"&gt;case&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语句。对&lt;/span&gt;&lt;span lang="EN-US"&gt;begin&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;块内的每个&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;将被引发异常与每个参数依次比较。如果被引发的异常匹配一个参数，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;执行这个&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句体并停止查找。这个匹配使用&lt;/span&gt;&lt;span lang="EN-US"&gt;parameter===$!&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作完成。对于大多数异常，这意味着如果&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句内的异常名若与当前被抛出的异常的类型相同，或是那个异常的一个子类，则匹配将会成功。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;注：这种比较这所以会发生，是因为异常是类，类是种模块。而模块内定义的&lt;/span&gt;&lt;span lang="EN-US"&gt;===&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，在做为操作数的类与被调的祖先相同时返回&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;如果你写了无参数&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句，则它的缺省参数是&lt;/span&gt;&lt;span lang="EN-US"&gt;StandardError&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果没有找到匹配的&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句，如果一个异常在&lt;/span&gt;&lt;span lang="EN-US"&gt;begin/end&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;块的外部被引发，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;在堆栈内移出调用者并从调用者内查找一个异常处理程序，然后是调用者内调用者，依次类推。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;尽管&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句的参数通常是&lt;/span&gt;&lt;span lang="EN-US"&gt;Exception&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类的名字，但实际上它们可以是能返回一个异常类的任意表达式&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;包括方法调用&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;系统错误&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;但调用操作系统并返回一个错误代码时系统错误被引发。在&lt;/span&gt;&lt;span lang="EN-US"&gt;POSIX&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;系统上，这些错误有如&lt;/span&gt;&lt;span lang="EN-US"&gt;EAGAIN&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;EPERM&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;等样的名字。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;如果你使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Unix&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;系统，你可以输入&lt;/span&gt;&lt;span lang="EN-US"&gt;manerrno&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来获得这些错误的列表。&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;接受这些错误并将它们包装一个特定的异常对象内。每个对象都是&lt;/span&gt;&lt;span lang="EN-US"&gt;SystemCallError&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的子类，每个对象都被定义在&lt;/span&gt;&lt;span lang="EN-US"&gt;Errno&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;模块内。这意味着将可使用类名称如&lt;/span&gt;&lt;span lang="EN-US"&gt;Errno::EAGAIN,Errno::EIO,&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;Errno::EPERM&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来寻找异常。如果你想获取操作系统的错误代码，每个&lt;/span&gt;&lt;span lang="EN-US"&gt;Errno&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;异常对象都有个类常量叫&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;有点乱&lt;/span&gt;&lt;span lang="EN-US"&gt;)Errno&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，它就包含这个值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Errno::EAGAIN::Errno &lt;span style=""&gt;&lt;/span&gt;=&gt; 35&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Errno::EPERM::Errno &lt;span style=""&gt;&lt;/span&gt;=&gt; 1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Errno::EIO::Errno &lt;span style=""&gt;&lt;/span&gt;=&gt; 5&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Errno::EWOULDBLOCK::Errno &lt;span style=""&gt;&lt;/span&gt;=&gt; 35&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;注意&lt;/span&gt;&lt;span lang="EN-US"&gt;EWOULDBLOCK&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;EAGAIN&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;有同样的错误号码。这是用于产生个块的计算机操作系统的一个特征&lt;/span&gt;&lt;span lang="EN-US"&gt;—&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;两个常量映射到同一错误号码。要处理它，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;会排列它们以便&lt;/span&gt;&lt;span lang="EN-US"&gt;Errno::EAGAIN&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;Errno::EWOULDBLOCK&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句中被同等对待。你在一个&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中请求，你就会处理这两者。通过重新定义&lt;/span&gt;&lt;span lang="EN-US"&gt;SystemCallError#===&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，以便&lt;/span&gt;&lt;span lang="EN-US"&gt;If you ask to rescue one, you’ll rescue either. It does this by redefining SystemCallError#=== so that if two subclasses of SystemCallError are compared, the comparison is done on their error number and not on their position in the hierarchy.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;清理&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;有时候你需要保证代码块的最后部分也会被处理，而不管是否有异常被引发。例如，你可能在进入块时打开一个文件，并且需要确保在块退出时文件会被关闭。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;使用&lt;/span&gt;&lt;span lang="EN-US"&gt;ensure&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句会做到这点。&lt;/span&gt;&lt;span lang="EN-US"&gt;ensure&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;出现在最后的&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句后面，它所包含的代码块在块中止时，总是会得到执行的。它不考虑块是正常退出，还是引发了异常及处理这个异常，或由一个未捕获异常而引起的中止，&lt;/span&gt;&lt;span lang="EN-US"&gt;ensure&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;块都将被执行。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;f = File.open("testfile")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;begin&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# .. process&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;rescue&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# .. handle error&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;ensure&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;f.close unless f.nil?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;else&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句也是一样的构造，尽管它不是很有用。如果出现的话，它在&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句的后面和任何&lt;/span&gt;&lt;span lang="EN-US"&gt;ensure&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句的前面。&lt;/span&gt;&lt;span lang="EN-US"&gt;else&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句体只有在主代码体没引发异常时才会被执行。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;f = File.open("testfile")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;begin&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# .. process&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;rescue&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# .. handle error&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts "Congratulationsno errors!"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;ensure&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;f.close unless f.nil?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;再次恢复执行&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;有时候你可能要纠正异常的错误。在这些情况下，你可以在一个&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句中使用&lt;/span&gt;&lt;span lang="EN-US"&gt;retry&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语句来重新进入到&lt;/span&gt;&lt;span lang="EN-US"&gt;begin/end&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;块中。明显地，这是个无穷尽的循环，所以使用这个特征要小心。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这个例子的代码会再次审理一个异常，可以查看&lt;/span&gt;&lt;span lang="EN-US"&gt;Minero Aoki&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span lang="EN-US"&gt;net/smtp.rb&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;库。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@esmtp = true&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;begin&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# First try an extended login. If it fails because the&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# server doesn't support it, fall back to a normal login&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if @esmtp then&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@command.ehlo(helodom)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@command.helo(helodom)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;rescue ProtocolError&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if @esmtp then&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@esmtp = false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;retry&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这个代码首先试图使用&lt;/span&gt;&lt;span lang="EN-US"&gt;EHLO&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;命令来连接一个&lt;/span&gt;&lt;span lang="EN-US"&gt;SMTP&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;服务，这个命令没有得到广泛的支持。如果连接失败，代码设置&lt;/span&gt;&lt;span lang="EN-US"&gt;@esmtp&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变量为&lt;/span&gt;&lt;span lang="EN-US"&gt;false&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，并且会试图重新连接。如果第二次又失败了，则引发异常给调用者。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;主动引发异常&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;到现在我们一直是在防御，处理由它人引发的异常。你也可反过来。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;你可以在你的代码中使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Kernel.raise&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;同义词是&lt;/span&gt;&lt;span lang="EN-US"&gt;Kernel.fail)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来引发异常。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise "bad mp3 encoding"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise InterfaceException, "Keyboard failure", caller&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;第一种形式只是简单地重新引发当前异常&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或者不是当前异常的&lt;/span&gt;&lt;span lang="EN-US"&gt;RuntimeError)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。这可以被用在需要在异常被传递前中途截住它的异常处理程序中。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;第二种形式创建一个新的&lt;/span&gt;&lt;span lang="EN-US"&gt;RuntimeError&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;异常，用指定字符串设定它的消息。然后在调用堆栈引这个异常。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;第三种形式的第一个参数创建一个异常，然后用第二个参数设置相关消息和堆栈轨迹给第三个参数。典型地，第一个参数即可以是异常层次内的类名字&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;注：技术上，这个参数可以是任何对象，该对象通过返回&lt;/span&gt;&lt;span lang="EN-US"&gt;object.kind_of?(Exception)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;为&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的对象来表示异常消息。&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，也可以是这些类的一个对象实例的引用。堆栈轨迹通常使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Kernel.caller&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法来产生。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这儿是些&lt;/span&gt;&lt;span lang="EN-US"&gt;raise&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的典型例子。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise "Missing name" if name.nil?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if i &gt;= names.size&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise IndexError, "#{i} &gt;= size (#{names.size})"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise ArgumentError, "Name too big", caller&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;在最后例子中，我们从堆栈轨迹中移除了当前例程，它通常在库模块中很有用。我们可使用这个特征。下面代码通过传递调用堆栈的一个子集给新的异常来从堆栈轨迹中移除两例程。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise ArgumentError, "Name too big", caller[1..1]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;给异常添加信息&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;你可以定义你自己的异常，它持有你需要传递给错误的任何信息。例如，某些类型的网络错误所依赖的环境是短暂的。如果这样一个错误发生，则环境是主要的，你可以在异常中设置个标志来告诉处理者，它是否值得去重新操作。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class RetryException &lt;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;attr :ok_to_retry&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def initialize(ok_to_retry)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@ok_to_retry = ok_to_retry&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;一个短暂的错误在代码的某处发生。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def read_data(socket)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;data = socket.read(512)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if data.nil?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise RetryException.new(true), "transient read error"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# .. normal processing&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;我们调用上一层堆栈来处理异常。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;begin&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;stuff = read_data(socket)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# .. process stuff&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;rescue RetryException =&gt; detail&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;retry if detail.ok_to_retry&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;Catch &lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;和&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt; Throw&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;raise&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;rescue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的异常机制中，当出现错误时，它们会放弃异常。有时候这很好，可让你在通常的处理期间从很深的嵌套结构中跳出来。此处的&lt;/span&gt;&lt;span lang="EN-US"&gt;catch&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;throw&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也很方便。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;catch (:done) do&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;while line = gets&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;throw :done unless fields = line.split(/t/)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;songlist.add(Song.new(*fields))&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;songlist.play&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;catch&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;定义带有给定名字&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;可以&lt;/span&gt;&lt;span lang="EN-US"&gt;Symbol&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;String)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;标签的块。块通常会被执行直到它遇见&lt;/span&gt;&lt;span lang="EN-US"&gt;throw&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;当&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;遇到一个&lt;/span&gt;&lt;span lang="EN-US"&gt;throw&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时，它展开调用堆栈来查找带有匹配符号的&lt;/span&gt;&lt;span lang="EN-US"&gt;catch&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;块。当找到时，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;在此点上展开堆栈并中止块。所以前面例子中，如果输入中不包含当前被格式化的行，&lt;/span&gt;&lt;span lang="EN-US"&gt;throw&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;将跳到相应的&lt;/span&gt;&lt;span lang="EN-US"&gt;catch&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的尾部，不只是中止&lt;/span&gt;&lt;span lang="EN-US"&gt;while&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;循环也跳过歌曲列表的播放。如果在调用&lt;/span&gt;&lt;span lang="EN-US"&gt;throw&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时使用了可选的第二个参数，则&lt;/span&gt;&lt;span lang="EN-US"&gt;catch&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的值会被做为返回值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;下面例子如果用户对提示的回答是&lt;/span&gt;&lt;span lang="EN-US"&gt;!&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时，使用&lt;/span&gt;&lt;span lang="EN-US"&gt;throw&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来中止与用户的会话。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def prompt_and_get(prompt)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print prompt&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;res = readline.chomp&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;throw :quit_requested if res == "!"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;res&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;catch :quit_requested do&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;name = prompt_and_get("Name: ")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;age = prompt_and_get("Age: ")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;sex = prompt_and_get("Sex: ")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# ..&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# process information&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;就像这个例子显示的，&lt;/span&gt;&lt;span lang="EN-US"&gt;throw&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;没有必要出现在&lt;/span&gt;&lt;span lang="EN-US"&gt;catch&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的静态作用域中。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28827285-115278462587352645?l=nucleusg.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/115278462587352645/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=28827285&amp;postID=115278462587352645' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278462587352645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278462587352645'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/2006/07/catchthrow.html' title='第八章 异常，catch和throw'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11202605830313623292'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28827285.post-115278455057892631</id><published>2006-07-13T18:55:00.000+09:00</published><updated>2006-07-13T18:55:50.706+09:00</updated><title type='text'>第七章 表达式(4-2)</title><content type='html'>&lt;p class="MsoNormal" align="center"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;第七章 表达式(4-2)&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family: 宋体;"&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UG"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;Defined?, And, Or, &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;和&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt; Not&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;支持所有标准的布尔操作，另外，还引入了新的操作符&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;defined&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;？&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span lang="EN-US"&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;操作符&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;and &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&amp;&amp;amp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;两者的值都为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;才会返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。第一个值为真，才会对第二个操作数求值&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;有时这也被称为短路求值&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。这两个操作符的区别是优先级不同（&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;and&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;低于&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; &amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;类似的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; or &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;|| &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;有一方操作数为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;就会返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。如果第一个为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;false&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，它们就会对第二个操作数求值。类似&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;and&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，这两个操作符只有优先级的不同。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;有趣的是，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;and&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;or&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;有相同的优先级，而&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的优先级高于&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;||&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;not&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;! &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;返回操作数的相反的值&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;如果操作数为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，则这个操作符返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;false,&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;如果操作数为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;false&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，则返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。并且&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;nod&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和！也只是优先级不同。&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;所有的这些操作符和优先级的总结在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;324&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页表&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;22.4&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中。&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;操作符&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;defined?&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;将返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;nil&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，如果参数&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;可以是任意表达式&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;没有定义的话。否则，将返回后面参数的描述信息。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;如果参数是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;yield&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;defined?(&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;在代码块与当前上下文环境关联&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;返回字符串&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;”yield”&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;defined? 1&lt;span style=""&gt; &lt;/span&gt;=&gt; "expression"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;defined? dummy &lt;span style=""&gt;&lt;/span&gt;=&gt; nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;defined? printf &lt;span style=""&gt;&lt;/span&gt;=&gt; "method"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;defined? String &lt;span style=""&gt;&lt;/span&gt;=&gt; "constant"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;defined? $_ &lt;span style=""&gt;&lt;/span&gt;=&gt; "globalvariable"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;defined? Math::PI &lt;span style=""&gt;&lt;/span&gt;=&gt; "constant"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;defined? a = 1 &lt;span style=""&gt;&lt;/span&gt;=&gt; "assignment"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;defined? 42.abs &lt;span style=""&gt;&lt;/span&gt;=&gt; "method"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;除了这些布尔表达式，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象还支持使用方法&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; ==, ===, &lt;=&gt;, =~, eql?, &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;equal?&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;进行对象之间的比较&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;见表&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;7.1)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。除了&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;=&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;之外这些操作符都在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Object&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类中定义，但是经常被子类重载。比如，类&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Array&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;重定义了&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;==&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，判断两个数组相同的条件事它们元素的个数相同，同一位置的元素也相同。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: center;" align="center"&gt;&lt;span style="font-size:130%;"&gt;&lt;b style=""&gt;&lt;span style="font-size: 9pt; font-family: Helvetica;" lang="EN-US"&gt;Table 7.1. &lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 9pt; font-family: 宋体;"&gt;通用比较操作符&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 9pt; font-family: Helvetica;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;table class="MsoTableGrid" style="border: medium none ; margin: auto auto auto 32.4pt; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr style=""&gt;&lt;td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 72pt; background-color: transparent;" valign="top" width="96"&gt;&lt;p class="MsoNormal" style="text-align: center;" align="center"&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: 宋体;"&gt;操作符&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Times-Bold;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-style: solid solid solid none; border-color: windowtext windowtext windowtext rgb(212, 208, 200); border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 315pt; background-color: transparent;" valign="top" width="420"&gt;&lt;p class="MsoNormal" style="text-align: center;" align="center"&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: 宋体;"&gt;意义&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 9pt; font-family: Helvetica;" lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=""&gt;&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 72pt; background-color: transparent;" valign="top" width="96"&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="font-size:130%;"&gt;==&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 315pt; background-color: transparent;" valign="top" width="420"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;测试值是否相等&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=""&gt;&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 72pt; background-color: transparent;" valign="top" width="96"&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="font-size:130%;"&gt;===&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 315pt; background-color: transparent;" valign="top" width="420"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;case&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语句的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;when&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句中用于每个条目与目标比较&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=""&gt;&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 72pt; background-color: transparent;" valign="top" width="96"&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="font-size:130%;"&gt;&lt;=&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 315pt; background-color: transparent;" valign="top" width="420"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;通用比较操作符。返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; −1, 0, &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; +1, &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;这依赖于被调小于，等于，大于它的参数。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=""&gt;&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 72pt; background-color: transparent;" valign="top" width="96"&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="font-size:130%;"&gt;&lt;, &lt;=, &gt;=, &gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 315pt; background-color: transparent;" valign="top" width="420"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;小于，小于等于，大于等于和大于的比较操作符。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=""&gt;&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 72pt; background-color: transparent;" valign="top" width="96"&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;=~&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 315pt; background-color: transparent;" valign="top" width="420"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;正则表达式模式匹配&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=""&gt;&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 72pt; background-color: transparent;" valign="top" width="96"&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="font-size:130%;"&gt;eql?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 315pt; background-color: transparent;" valign="top" width="420"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果被调和参数两者类型相同并且值相等返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;1 == 1.0&lt;/span&gt;&lt;/b&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，但是&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;1.eql?(1.0)&lt;/span&gt;&lt;/b&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=""&gt;&lt;td style="border-style: none solid solid; border-color: rgb(212, 208, 200) windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 72pt; background-color: transparent;" valign="top" width="96"&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="font-size:130%;"&gt;equal?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-style: none solid solid none; border-color: rgb(212, 208, 200) windowtext windowtext rgb(212, 208, 200); border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 315pt; background-color: transparent;" valign="top" width="420"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果被调和参数有同样的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;ObjectID&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal" style="text-indent: 21.1pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;==&lt;/span&gt;&lt;/b&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; =~ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;两者有否定形式&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;, != and !~. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;但是，当你的程序被读入时这些会由&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;转换。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;a != b &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;与&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; !(a&lt;b style=""&gt; ==&lt;/b&gt; b)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是相等的，而&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; a !~ b &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;与&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; !(a =~ b)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也是一样的。&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;这意味着如果你的类覆写了&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;==&lt;/span&gt;&lt;/b&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; =~ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，你会自动得到&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;!= &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; !~ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。同时，你也不能离开了&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;==&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;=~&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;而孤立的定义&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;!=&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;!~&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;两个方法。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt; text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;你可以使用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby range &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;作为一个布尔表达式，一个类似&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; exp1..exp2 &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;range&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;只有在遇到&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;exp1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，然后&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;exp2&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;又为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;之后，才会返回&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。我们将在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;94&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页显示这个例子。&lt;/span&gt;&lt;span style="font-size: 10pt; color: black; font-family: Times-Roman;" lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;先前的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby1.8&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，你可以用正则表达式来当作一个布尔表达式。现在不赞成这样做。你仍可以使用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;~&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作符&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;(580&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页描述的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来与一个模式匹配&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;$_&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;逻辑表达式的值&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在书中，我们这样说&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;”&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;如果两个操作符是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，则求值为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;”&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。但实际上要比这复杂些。操作符&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;and&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;or,&amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;||&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;实际上返回它们的第一参数，该参数决定条件的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;false&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。重要的是，这是什么意思？&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;拿表达式&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;”val1 and val&lt;chmetcnv unitname="”" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;2”&lt;/chmetcnv&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来说，如果&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;val1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;false&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;nil&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，那么我们知道这个表达式不会为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。在这种情况下，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;val1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的值决定了表达式的整个值，所以它是被返回的值。如果&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;val1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;有其它值，那么整个表达式值则依赖于&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;val2&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，因此它值是返回值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;nil and true &lt;span style=""&gt;&lt;/span&gt;=&gt; nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;false and true &lt;span style=""&gt;&lt;/span&gt;=&gt; false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;99 and false &lt;span style=""&gt;&lt;/span&gt;=&gt; false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;99 and nil &lt;span style=""&gt;&lt;/span&gt;=&gt; nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;99 and "cat" &lt;span style=""&gt;&lt;/span&gt;=&gt; "cat"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;Note that despite all this magic, the overall truth value of the expression is correct.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;The same evaluation takes place for or (except an or expression’s value is known early if val1 is not false).&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;false or nil &lt;span style=""&gt;&lt;/span&gt;=&gt; nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;nil or false &lt;span style=""&gt;&lt;/span&gt;=&gt; false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;99 or false &lt;span style=""&gt;&lt;/span&gt;=&gt; 99&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;A common Ruby idiom makes use of this.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;words[key] ||= []&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;words[key] &lt;&lt;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;The first line is equivalent to words[key] = words[key] || []. If the entry in the hash words for key is unset (nil), the value of || will be the second operand, a new, empty array. Thus, this line of code will assign an array to a hash element that doesn’t already have a value, leaving it untouched otherwise. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;有时你也会看到将它们写一行上：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;(words[key] ||= []) &lt;&lt;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UH"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;If &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;和&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt; Unless&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;表达式&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语句跟其他语言类似。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if song.artist == "Gillespie" then&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;handle = "Dizzy"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;elsif song.artist == "Parker" then&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;handle = "Bird"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;handle = "unknown"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果你的&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语句写在多行上，可以省略&lt;/span&gt;&lt;span lang="EN-US"&gt;then&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;关键字。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if song.artist == "Gillespie"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;handle = "Dizzy"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;elsif song.artist == "Parker"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;handle = "Bird"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;handle = "unknown"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;但是，如果你的语句都写在一行上，&lt;/span&gt;&lt;span lang="EN-US"&gt;then&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;关键字应该写上来分开布尔表达式和后面的语句。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if song.artist == "Gillespie" then handle = "Dizzy"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;elsif song.artist == "Parker" then handle = "Bird"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else handle = "unknown"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;1.8&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中你也可使用冒号：来替换&lt;/span&gt;&lt;span lang="EN-US"&gt;then&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，使代码更简洁些。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if song.artist == "Gillespie": handle = "Dizzy"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;elsif song.artist == "Parker": handle = "Bird"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else handle = "unknown"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;你可以使用&lt;/span&gt;&lt;span lang="EN-US"&gt;0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个或多个&lt;/span&gt;&lt;span lang="EN-US"&gt;elsif&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句，和一个可选的&lt;/span&gt;&lt;span lang="EN-US"&gt;else&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;子句。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;就像我们前面说道的，&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是一个表达式，不是一个语句，它可以返回一个值，你不必使用&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;表达式的返回值，但是它可能有些用处。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;handle = if song.artist == "Gillespie" then&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 115.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"Dizzy"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;elsif song.artist == "Parker" then&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 115.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"Bird"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 115.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"unknown"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也未&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;提供了一个否定的形式，&lt;/span&gt;&lt;span lang="EN-US"&gt;unless&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;unless song.duration &gt; 180&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;cost = 0.25&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;cost = 0.35&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;最后，也为使用&lt;/span&gt;&lt;span lang="EN-US"&gt;C&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语言的程序员准备了&lt;/span&gt;&lt;span lang="EN-US"&gt;C&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;风格的条件表达式：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;cost = song.duration &gt; 180 ? 0.35 : 0.25&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这个条件表达式在根据&lt;/span&gt;&lt;span lang="EN-US"&gt;?&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;前面的布尔值为&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;false&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;返回冒号前面或后面的值。在这个例子中，如果歌曲的时长大于&lt;/span&gt;&lt;span lang="EN-US"&gt;3&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;分钟，将返回&lt;/span&gt;&lt;span lang="EN-US"&gt;.35&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，否则返回&lt;/span&gt;&lt;span lang="EN-US"&gt;.25&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，然后，将这个值赋给&lt;/span&gt;&lt;span lang="EN-US"&gt;cost&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UI"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;If &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;和&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt; Unless &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;修饰句&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也借鉴了&lt;/span&gt;&lt;span lang="EN-US"&gt;Perl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的一些特点，语句修饰句使我们可以在普通语句的末尾加上条件语句。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;mon, day, year = $1, $2, $3 if date =~ /(dd)(dd)(dd)/&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts "a = #{a}" if debug&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print total unless total.zero?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;对于&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;修饰句来说，只有当&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;后面的条件为&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，前面的语句才会执行，&lt;/span&gt;&lt;span lang="EN-US"&gt;unless&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;正好和&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;相反。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;File.foreach("/etc/fstab") do |line|&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;next if line =~ /^#/&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;# Skip comments&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;parse(line) unless line =~ /^$/ &lt;span style=""&gt;&lt;/span&gt;# Don't parse empty lines&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;因为&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;本身也是表达式，所以下面的写法将会使代码变得难懂。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if artist == "John Coltrane"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;artist = "'Trane"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end unless use_nicknames == "no"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;This path leads to the gates of madness.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28827285-115278455057892631?l=nucleusg.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/115278455057892631/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=28827285&amp;postID=115278455057892631' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278455057892631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278455057892631'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/2006/07/4-2.html' title='第七章 表达式(4-2)'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11202605830313623292'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28827285.post-115278447775696502</id><published>2006-07-13T18:54:00.000+09:00</published><updated>2006-07-13T18:54:37.900+09:00</updated><title type='text'>第七章 表达式(4-1)</title><content type='html'>&lt;p class="MsoNormal" style="text-indent: 21pt;" align="center"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;第七章 表达式(4-1)&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;到目前为止我们已经用了一些基本的表达式，毕竟，&lt;/span&gt;&lt;span lang="EN-US"&gt;a&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;＝&lt;/span&gt;&lt;span lang="EN-US"&gt;b&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;＋&lt;/span&gt;&lt;span lang="EN-US"&gt;c&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是最基本的了，你即使不看本章，也能写出一大堆的&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;代码来。但是那样做不是什么有趣的事情&lt;/span&gt;&lt;span lang="EN-US"&gt;;-)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;&lt;br /&gt;&lt;span style="font-family: 宋体;"&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和其它语言的一个不同之处就是任何东西都能返回一个值：几乎所有的东西都是个表达式。在实际中，这有什么意义呢？&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;一些明显得作用是可以实现链式语句：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = b = c = 0 &lt;span style=""&gt;&lt;/span&gt;=&gt; 0&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;[ 3, 1, 7, 0 ].sort.reverse &lt;span style=""&gt;&lt;/span&gt;=&gt; [7, 3, 1, 0]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;或许不是很明显，&lt;/span&gt;&lt;span lang="EN-US"&gt;C&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;JAVA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中通常的语句，在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中都是表达式。例如，&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;case&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;两者都返回最后的表达式执行后返回的值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;song_type = if song.mp3_type == MP3::Jazz&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 136.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if song.written &lt;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 152.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Song::TradJazz&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 136.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 152.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Song::Jazz&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 136.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 115.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 136.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Song::Other&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 115.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;rating = case votes_cast&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 105pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;when 0...10 then Rating::SkipThisOne&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 105pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;when 10...50 then Rating::CouldDoBetter&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 105pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else Rating::Rave&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;我们会在&lt;/span&gt;&lt;span lang="EN-US"&gt;90&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页祥细地讨论&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;case&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语句。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S1"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;操作符表达式&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;提供的基本操作符集&lt;/span&gt;&lt;span lang="EN-US"&gt;()&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;让人有些惊讶。完整的操作符列表和优先级在&lt;/span&gt;&lt;span lang="EN-US"&gt;324&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页表&lt;/span&gt;&lt;span lang="EN-US"&gt;22.4&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中给出。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，很多操作符实际上是做为方法调用实现的。例如，当你执行&lt;/span&gt;&lt;span lang="EN-US"&gt;a*b+c&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时，实际上是对&lt;/span&gt;&lt;span lang="EN-US"&gt;a&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的对象引用执行方法&lt;/span&gt;&lt;span lang="EN-US"&gt;*&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，传递参数&lt;/span&gt;&lt;span lang="EN-US"&gt;b&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;给它。然后你请求从做为计算结果的对象上再执行&lt;/span&gt;&lt;span lang="EN-US"&gt;+&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，传递参数&lt;/span&gt;&lt;span lang="EN-US"&gt;c&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;给它。这实际上等于写：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;(a.*(b)).+(c)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt; text-align: left;" align="left"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;因为万物皆对象，所以你可以重定义实例方法，如果你不喜欢现有基本操作符的工作方式，你总是可以重新定义它。&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Times-Roman;" lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Fixnum&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;alias old_plus +&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# Redefine addition of Fixnums. This is a BAD IDEA!&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def +(other)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;old_plus(other).succ&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;1 + 2 &lt;span style=""&gt;&lt;/span&gt;=&gt; 4&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = 3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a += 4 &lt;span style=""&gt;&lt;/span&gt;=&gt; 8&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a + a + a &lt;span style=""&gt;&lt;/span&gt;=&gt; 26&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;很有用的一个技巧是你自己写的的类可以像内建对象一样参与操作符的操作，比如，我们想从一首歌中间某处开始提取一部分音乐，我们可以用索引操作符&lt;/span&gt;&lt;span lang="EN-US"&gt;"[ ]"&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来完成对指定音乐的抽取：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Song&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def [](from_time, to_time)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;result = Song.new(self.title + " [extract]",self.artist,to_time from_time)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;result.set_start_time(from_time)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这段代码扩展了类&lt;/span&gt;&lt;span lang="EN-US"&gt;Song&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，增加了&lt;/span&gt;&lt;span lang="EN-US"&gt;[ ]&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，这个方法接收两个参数&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;开始时间和结束时间&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。这个方法返回一个新的&lt;/span&gt;&lt;span lang="EN-US"&gt;Song&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象，这个对象是歌曲的一部分。然后，我们就可以这样播放这段音乐：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;song[0, 15].play&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S2"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;混合表达式（&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;Miscellaneous Expressions&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;除了明显的操作符表达式和方法调用，和不是很显眼的语句表达式（比如&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;case&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;），&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;还支持在表达式中使用更多的东西。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UA"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;命令展开&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;"&gt; &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;（&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;Command Expansion&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果你用反引号（&lt;/span&gt;&lt;span lang="EN-US"&gt;`&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）来括起来一个字符串，或者用定界形式的前缀&lt;/span&gt;&lt;span lang="EN-US"&gt;%x{ &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt; }&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;括起来，那么这个表达式中的字符串默认得会作为底层的操组系统命令来执行。表达式的值是那个命令的标准输出。换行符将不会从结果中去掉，所以返回结果一般都会包含一个回车符。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;`date` &lt;span style=""&gt;&lt;/span&gt;=&gt; "Thu Aug 26 22:36:31 CDT 2004n"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;`ls`.split[34] &lt;span style=""&gt;&lt;/span&gt;=&gt; "book.out"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;%x{echo "Hello there"} &lt;span style=""&gt;&lt;/span&gt;=&gt; "Hello theren"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;你也可以在命令字符串中使用表达式展开和所有通常的转义序列。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;for i in 0..3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;status = `dbmanager status id=#{i}`&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# ...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;执行的命令的返回状态存放在全局变量&lt;/span&gt;&lt;span lang="EN-US"&gt;$?&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UB"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;重定义反引号方法&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在命令输出表达式中描述中，我们说，反引号之中的字符串将&lt;/span&gt;&lt;span lang="EN-US"&gt;"&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;默认&lt;/span&gt;&lt;span lang="EN-US"&gt;"&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;被做为一个命令来执行。实际上，这个字符串是传递给了&lt;/span&gt;&lt;span lang="EN-US"&gt;Kernel::` &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;这个方法（一个反引号）来执行。如果你愿意，可以重写这个方法。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;alias old_backquote `&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def `(cmd)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;result = old_backquote(cmd)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if $? != 0&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;fail "Command #{cmd} failed: #$?"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print `date`&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print `data`&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Thu Aug 26 22:36:31 CDT 2004&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;prog.rb:10: command not found: data&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;prog.rb:5:in ``': Command data failed: 32512 (RuntimeError)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;from prog.rb:10&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S3"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;赋值&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;我们前面的例子中都涉及到了赋值这一基本表达式，下面，我们来讨论一些关于赋值语句的东西。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;一个赋值语句给在左侧的一个变量或属性&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;左值&lt;/span&gt;&lt;span lang="EN-US"&gt;lvalue)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;设定一个在它右侧指定的值&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;右值&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。然后这个值作为赋值表达式的返回值返回。也就是说，我们可以用链式赋值来给一些变量赋值：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = b = 1 + 2 + 3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a &lt;span style=""&gt;&lt;/span&gt;=&gt; 6&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b &lt;span style=""&gt;&lt;/span&gt;=&gt; 6&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = (b = 1 + 2) + 3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a &lt;span style=""&gt;&lt;/span&gt;=&gt; 6&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b &lt;span style=""&gt;&lt;/span&gt;=&gt; 3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;File.open(name = gets.chomp)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中有两种基本的赋值格式，第一种是将对象引用赋值给变量或常量。这种形式被紧密连接到语言中的。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;instrument = "piano"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;MIDDLE_A = 440&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;另一种是在赋值语句左边使用对象的属性或者元素的引用。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;song.duration = 234&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;instrument["ano"] = "ccolo"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;这些形式比较特殊，因为它们是通过调用左值的方法来实现的，它意味着你可覆写它们。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;我们已经看过如何定义一个可修改的对象属性。只需要简单的在方法后面以等号结尾即可。这个方法把接收的参数作为赋值语句的右值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Song&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def duration=(new_duration)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@duration = new_duration&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这些属性设置方法没有必须与内部的实例变量一致，你也不需要为每个属性提供读取方法&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;反过来也是一样&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Amplifier&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def volume=(new_volume)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;self.left_channel = self.right_channel = new_volume&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 24pt;"&gt;&lt;span style="font-size: 12pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;在老&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;版本中，赋值语句的结果是由属性设置方法返回的值。在&lt;span lang="EN-US"&gt;1.8&lt;/span&gt;中，赋值的值总是参数的值；方法的返回值被丢弃。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Test&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def val=(val)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@val = val&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;return 99&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;t = Test.new&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = t.val = 2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a &lt;span style=""&gt;&lt;/span&gt;=&gt; 2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在老版本中，&lt;/span&gt;&lt;span lang="EN-US"&gt;a&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;被赋值语句设置为&lt;/span&gt;&lt;span lang="EN-US"&gt;99&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，在&lt;/span&gt;&lt;span lang="EN-US"&gt;1.8&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中被设置为&lt;/span&gt;&lt;span lang="EN-US"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: center;" align="center"&gt;&lt;b&gt;&lt;span style="font-size: 12pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;在类中使用存取器方法&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt; text-align: left;" align="left"&gt;&lt;span style="font-family: 宋体;" lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;84&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;页中的例子中为什么我们必须要写&lt;span lang="EN-US"&gt; self.leftChannel &lt;/span&gt;而不能省掉&lt;span lang="EN-US"&gt;self&lt;/span&gt;呢？一般的，可修改属性都有一个隐藏的&lt;span lang="EN-US"&gt;gotcha&lt;/span&gt;。通常，一个类中的方法可以直接调用同类或者父类中的其他方法（也就是说，暗中带有&lt;span lang="EN-US"&gt;self&lt;/span&gt;被调）。但是，对于属性修改方法来说这就不管用了，&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;将把左面的名字作为一个局部变量，而不是一个对写属性方法的调用。　&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class BrokenAmplifier&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;attr_accessor :left_channel, :right_channel&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def volume=(vol)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;left_channel = self.right_channel = vol&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;ba = BrokenAmplifier.new&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;ba.left_channel = ba.right_channel = 99&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;ba.volume = 5&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;ba.left_channel &lt;span style=""&gt;&lt;/span&gt;=&gt; 99&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;ba.right_channel &lt;span style=""&gt;&lt;/span&gt;=&gt; 5&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;leftChannel&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;前面忘了写&lt;/span&gt;&lt;span lang="EN-US"&gt;self.&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;了，所以&lt;/span&gt;&lt;span lang="EN-US"&gt;ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;把这个新值赋给了一个方法&lt;/span&gt;&lt;span lang="EN-US"&gt;volume&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;＝的一个局部变量，而这个对象的属性没有任何变化。这可能会经常产生问题。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UC"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;并行赋值&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;在学习了一段时间程序设计之后，我们可能会遇到要求将两个变量的值互换：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;int a = 1;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;int b = 2;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;int temp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;temp = a;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = b;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b = temp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中很简单，只需要：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a, b = b, a&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;可以有效的实现并行赋值，所以被分派的值不会影响到赋值本身。在右边的值在被赋给左面的变量或属性之前按照它们的顺讯进行求值，然后对应的赋给左面的属性或变量。一个例子如下，第二行给&lt;/span&gt;&lt;span lang="EN-US"&gt;a&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;b&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;c&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的值分别是&lt;/span&gt;&lt;span lang="EN-US"&gt;x&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;x&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;＋＝&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;x&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;＋＝&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;计算之后的值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;x = 0 &lt;span style=""&gt;&lt;/span&gt;=&gt; 0&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a, b, c = x, (x += 1), (x += 1) &lt;span style=""&gt;&lt;/span&gt;=&gt; [0, 1, 2]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;当一个赋值语句有多于一个的左值时，这个赋值表达式返回值是个右值的数组。如果一个赋值语句的左值多余右值，多余的左值被设为&lt;/span&gt;&lt;span lang="EN-US"&gt;nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，反过来如果右值多余左值，那么多余的右值将被忽略。如果左值只有一个，右值有多个，那么这些右值将作为一个数组赋给左值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;你也可以在并行赋值语句中分解和扩展数组。如果最后的左值以星号作为前缀，那么所有对应这个得值和以后的值将会组成一个数组，赋给这个左值（如下面第三行的&lt;/span&gt;&lt;span lang="EN-US"&gt;c&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）；类似的，如果最后一个右值是一个数组，你可以加一个星号作为前缀，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;将会把这个数组拆开按相应的位置赋给左值（如下面第六行的&lt;/span&gt;&lt;span lang="EN-US"&gt;c&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，而且，如果这个数组是唯一的右值，这个星号是可以省略的，作为右值得数组自动拆开，如第二行所示）。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = [1, 2, 3, 4]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, c = a&lt;span style=""&gt; &lt;/span&gt;=&gt; b == 1, c == 2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, *c = a &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 1, c == [2, 3, 4]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, c = 99, a &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 99, c == [1, 2, 3, 4]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, *c = 99, a &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 99, c == [[1, 2, 3, 4]]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, c = 99, *a &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 99, c == 1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, *c = 99, *a &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 99, c == [1, 2, 3, 4]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UD"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;嵌套赋值&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;并行赋值还有一个值得一提的特性，赋值语句左边还可以包括用括号括起来的变量列表，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中叫做嵌套赋值语句。&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;首先摘出右值中相应的项进行赋值，然后在进行高层的赋值操作。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, (c, d), e = 1,2,3,4 &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 1, c == 2, d == nil, e == 3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, (c, d), e = [1,2,3,4] &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 1, c == 2, d == nil, e == 3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, (c, d), e = 1,[2,3],4 &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 1, c == 2, d == 3, e == 4&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, (c, d), e = 1,[2,3,4],5 &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 1, c == 2, d == 3, e == 5&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b, (c,*d), e = 1,[2,3,4],5 &lt;span style=""&gt;&lt;/span&gt;=&gt; b == 1, c == 2, d == [3, 4], e == 5&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UE"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;其它赋值形式&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;像其它语言一样，&lt;/span&gt;&lt;span lang="EN-US"&gt;ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;也为&lt;/span&gt;&lt;span lang="EN-US"&gt;a=a+2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;提供了类似&lt;/span&gt;&lt;span lang="EN-US"&gt;a+=2&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的快捷方式。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;第二种方式是第一种的深入，这意味着你已定义的那个操作符在你的类内可做为方法来工作。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Bowdlerize&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def initialize(string)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@value = string.gsub(/[aeiou]/, '*')&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def +(other)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Bowdlerize.new(self.to_s + other.to_s)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def to_s&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@value&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = Bowdlerize.new("damn ") &lt;span style=""&gt;&lt;/span&gt;=&gt; d*mn&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a += "shame" &lt;span style=""&gt;&lt;/span&gt;=&gt; d*mn sh*m*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;你不会在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中找到&lt;/span&gt;&lt;span lang="EN-US"&gt;C&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;Java&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的增量&lt;/span&gt;&lt;span lang="EN-US"&gt;(++)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和减量&lt;/span&gt;&lt;span lang="EN-US"&gt;(--)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作符。使用&lt;/span&gt;&lt;span lang="EN-US"&gt;+=&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;=&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;形式来代替。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S4"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;条件执行（&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;Conditional Execution&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;）&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;有几种不同的机制来实现代码的条件执行；大多数都感觉很类似，也有一些很灵巧。在深入讨论之前，我们先来花点时间看看布尔表达式。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UF"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Boolean &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;表达式&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;定义很简单。任何不是&lt;/span&gt;&lt;span lang="EN-US"&gt;nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和常量&lt;/span&gt;&lt;span lang="EN-US"&gt;false&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的东西都是&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。你会发现系统的实现库中很多这种用法。比如，&lt;/span&gt;&lt;span lang="EN-US"&gt;IO#gets &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，用来返回一个文件的下一行，如果到了文件末尾，返回&lt;/span&gt;&lt;span lang="EN-US"&gt;nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，所以，我们才可以这样通过&lt;/span&gt;&lt;span lang="EN-US"&gt;while&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来循环读取数据：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;while line = gets&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# process line&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;但是，这里对于&lt;/span&gt;&lt;span lang="EN-US"&gt;C&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;C++&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;perl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;程序员来说有一个误区，数字&lt;/span&gt;&lt;span lang="EN-US"&gt;0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和长度为&lt;/span&gt;&lt;span lang="EN-US"&gt;0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的字符串都不会被解释成&lt;/span&gt;&lt;span lang="EN-US"&gt;false&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;值，需要注意。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28827285-115278447775696502?l=nucleusg.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/115278447775696502/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=28827285&amp;postID=115278447775696502' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278447775696502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278447775696502'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/2006/07/4-1.html' title='第七章 表达式(4-1)'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11202605830313623292'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28827285.post-115278439145951465</id><published>2006-07-13T18:52:00.000+09:00</published><updated>2006-07-13T18:53:11.566+09:00</updated><title type='text'>第六章 深入方法</title><content type='html'>&lt;p class="MsoNormal" style="text-indent: 21pt;" align="center"&gt;&lt;span style="font-family:宋体;"&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;第六章 深入方法&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;一些其它语言有函数，过程，方法等，而&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中只有方法：一段表达式代码，返回一个值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;到目前为止，我们在这本书中只是基本的介绍了如何定义，使用方法，现在，我们会继续深入的探讨一些关于方法更深层的东西。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S1"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;方法定义&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;如同在前面看到的一样，定义一个方法用关键字&lt;/span&gt;&lt;span lang="EN-US"&gt;def&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。方法名应该以小写字母开头。&lt;/span&gt;&lt;span lang="EN-US"&gt;[&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;如果你用大写字母开头定义一个方法，你不会立即得到一个错误，但是当你调用这个方法时，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;首先认为你访问的是一个常量，所以可能会解析错误&lt;/span&gt;&lt;span lang="EN-US"&gt;]&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;被用来做为查询的方法通常名字后面带有一个问号&lt;/span&gt;&lt;span lang="EN-US"&gt;"?"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。例如，&lt;/span&gt;&lt;span lang="EN-US"&gt;String&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;提供了&lt;/span&gt;&lt;span lang="EN-US"&gt;chop&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;chop!&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;两个方法，第一个方法返回一个修改过的字符串，而第二个方法直接就修改了被调本身。可以用来进行赋值的方法的名字后面带有等号&lt;/span&gt;&lt;span lang="EN-US"&gt;(=)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;span lang="EN-US"&gt;"?"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;"!"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;"="&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;只允许做为方法名字的后缀。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;现在，我们已经指定了我们新方法的名字，如果需要，我们可以定义一些参数。这些是在圆括号内的简单的一个局部变量列表。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;包围方法的参数的圆括号是可选的；我们约定，方法有参数时使用它们，没有参数时省略它们。&lt;/span&gt;&lt;span lang="EN-US"&gt;) &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;def my_new_method(arg1, arg2, arg3) &lt;span style=""&gt;&lt;/span&gt;# 3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;个参数&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# Code for the method would go here&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;def my_other_new_method &lt;span style=""&gt;&lt;/span&gt;#&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;无参数&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# Code for the method would go here&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;允许为方法的参数设置默认值：如果调用者没有显示的为这些参数提供值，将使用这些默认值。通过&lt;/span&gt;&lt;span lang="EN-US"&gt;"="&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，就可以为这些参数设定默认值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def cool_dude(arg1="Miles", arg2="Coltrane", arg3="Roach")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"#{arg1}, #{arg2}, #{arg3}."&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;cool_dude &lt;span style=""&gt;&lt;/span&gt;=&gt; "Miles, Coltrane, Roach."&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;cool_dude("Bart")&lt;span style=""&gt; &lt;/span&gt;=&gt; "Bart, Coltrane, Roach."&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;cool_dude("Bart", "Elwood")&lt;span style=""&gt; &lt;/span&gt;=&gt; "Bart, Elwood, Roach."&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;cool_dude("Bart", "Elwood", "Linus") &lt;span style=""&gt;&lt;/span&gt;=&gt; "Bart, Elwood, Linus."&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;方法体中包含了一般的&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;表达式，但是你不能在方法里面定义非单态类或者模块。如果你在另一个方法内定义了一个方法，则当外部方法被执行时，内部的方法被定义。方法的返回值是方法体最后表达式被执行后的结果，或者你显示的用一个&lt;/span&gt;&lt;span lang="EN-US"&gt;return&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;语句。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UA"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;可变长度的参数列表&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;如果我们想给方法传入一个数目不定的参数，或者把所有参数放到一个参数中进行传递的话，该怎么办呢？我们可以在普通的参数后面加入一个特殊的参数，这个参数以&lt;/span&gt;&lt;span lang="EN-US"&gt;"*"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;开头，就可以达到这个目的了。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def varargs(arg1, *rest)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"Got #{arg1} and #{rest.join(', ')}"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;varargs("one") &lt;span style=""&gt;&lt;/span&gt;=&gt; "Got one and "&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;varargs("one", "two") &lt;span style=""&gt;&lt;/span&gt;=&gt; "Got one and two"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;varargs "one", "two", "three" &lt;span style=""&gt;&lt;/span&gt;=&gt; "Got one and two, three"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;在这个例子中，第一个参数很普通，直接作为第一个参数变量，而后面以&lt;/span&gt;&lt;span lang="EN-US"&gt;"*"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;开头的参数，将会包括调用时候后面的所有参数，是一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的结构，包括了从第二个开始的所有参数。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UB"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;方法和块&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt; text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;46&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;页讨论块和迭代的那章时，我们知道，当一个方法被调用时候，可以接收一个块。通常，你只是简单地在方法内使用&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来调用这个块。&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Times-Roman;font-size:10;color:black;"   lang="EN-US" &gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def take_block(p1)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if block_given?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;yield(p1)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;p1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;take_block("no block") &lt;span style=""&gt;&lt;/span&gt;=&gt; "no block"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;take_block("no block") {|s| s.sub(/no /, '') } &lt;span style=""&gt;&lt;/span&gt;=&gt; "block"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;但是，当方法接受参数中最后一个参数以&lt;/span&gt;&lt;span lang="EN-US"&gt;"&amp;"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;开始的时候，任何与之关联的块都会转换为&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象，并且这个&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象将会赋值给这个参数（下例中&lt;/span&gt;&lt;span lang="EN-US"&gt;block&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;指向一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象）。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class TaxCalculator&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def initialize(name, &amp;block)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@name, @block = name, block&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def get_tax(amount)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"#@name on #{amount} = #{ @block.call(amount) }"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;tc = TaxCalculator.new("Sales tax") {|amt| amt * 0.075 }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;tc.get_tax(100)&lt;span style=""&gt; &lt;/span&gt;=&gt; "Sales tax on 100 = 7.5"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;tc.get_tax(250) &lt;span style=""&gt;&lt;/span&gt;=&gt; "Sales tax on 250 = 18.75"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S2"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;调用方法&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;通常，调用一个方法需要指定一个被调，方法名子，还有一些可选参数或者可选的块。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;connection.download_MP3("jitterbug") {|p| show_progress(p) }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;在这个例子里，&lt;/span&gt;&lt;span lang="EN-US"&gt;connection&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是被调，&lt;/span&gt;&lt;span lang="EN-US"&gt;downloadMP3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是方法名，&lt;/span&gt;&lt;span lang="EN-US"&gt;"jitterbug"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是一个参数，&lt;/span&gt;&lt;span lang="EN-US"&gt;{ |p| showProgress(p) }&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是传递给这个方法的块。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;对于类或者模块方法来说，被调是类或模块名：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;File.size("testfile") &lt;span style=""&gt;&lt;/span&gt;=&gt; 66&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Math.sin(Math::PI/4) &lt;span style=""&gt;&lt;/span&gt;=&gt; 0.707106781186548&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;如果你省略了被调，那么默认为&lt;/span&gt;&lt;span lang="EN-US"&gt;self&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是被调，即当前对象：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;self.class &lt;span style=""&gt;&lt;/span&gt;=&gt; Object&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;self.frozen? &lt;span style=""&gt;&lt;/span&gt;=&gt; false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;frozen? &lt;span style=""&gt;&lt;/span&gt;=&gt; false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;self.id &lt;span style=""&gt;&lt;/span&gt;=&gt; 967900&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;id &lt;span style=""&gt;&lt;/span&gt;=&gt; 967900&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;这种缺省机制也是&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;实现&lt;/span&gt;&lt;span lang="EN-US"&gt;private&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;方法的体现，&lt;/span&gt;&lt;span lang="EN-US"&gt;private&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;方法不能用一个被调来直接调用，只能在当前对象中使用。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;同样，在前个例子中，我们调用&lt;/span&gt;&lt;span lang="EN-US"&gt;self.class&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，但我们没有使用一个被调来调用这个方法。这是因为&lt;/span&gt;&lt;span lang="EN-US"&gt;class&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;也是&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的一个关键字&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;它引入类定义&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，所以使用的话会产生一个语法错误。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;方法名后面是可选的参数，如果不会出现歧义的话，调用方法时参数可以不加括号括起来&lt;/span&gt;&lt;span lang="EN-US"&gt;[Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;文档有时候也叫做这样的方法是命令（&lt;/span&gt;&lt;span lang="EN-US"&gt;commands&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;）&lt;/span&gt;&lt;span lang="EN-US"&gt;]&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，然而，除非是特别简单的情况，否则还是加上括号的好，要不可能容易出错。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;特别地，当被调用的方法是另一个方法的参数时，你必须使用圆括号。除非它是最后一个参数&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;我们的规则很简单：如果有任何歧义，使用圆括号。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = obj.hash &lt;span style=""&gt;&lt;/span&gt;# Same as&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = obj.hash() &lt;span style=""&gt;&lt;/span&gt;# this.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;obj.some_method "Arg1", arg2, arg3 &lt;span style=""&gt;&lt;/span&gt;# Same thing as&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;obj.some_method("Arg1", arg2, arg3)&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;# with parentheses.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UC"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;方法返回的值&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;每个被调用的方法返回一个值&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;尽管没有规定说你必须使用这个值&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;。方法的值是在方法执行期间被计算的最后语句的值。&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;有个&lt;/span&gt;&lt;span lang="EN-US"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;语句，它从当前运行的方法中退出。&lt;/span&gt;&lt;span lang="EN-US"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;的值是它的参数。如果不需要，则&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;习惯上是省略这个参数。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def meth_one&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"one"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;meth_one &lt;span style=""&gt;&lt;/span&gt;=&gt; "one"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def meth_two(arg)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;case&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;when arg &gt; 0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"positive"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;when arg &lt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"negative"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"zero"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;meth_two(23) &lt;span style=""&gt;&lt;/span&gt;=&gt; "positive"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;meth_two(0) &lt;span style=""&gt;&lt;/span&gt;=&gt; "zero"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def meth_three&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;100.times do |num|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;square = num*num&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;return num, square if square &gt; 1000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;meth_three &lt;span style=""&gt;&lt;/span&gt;=&gt; [32, 1024]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;就像最后一个&lt;/span&gt;&lt;span lang="EN-US"&gt;case&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;显示的，如果你给出有多个参数的&lt;/span&gt;&lt;span lang="EN-US"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;语句，则方法将在一个数组中返回它们。你可以使用并行赋值来收集这个返回值。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;num, square = meth_three&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;num &lt;span style=""&gt;&lt;/span&gt;=&gt; 32&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;square &lt;span style=""&gt;&lt;/span&gt;=&gt; 1024&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;在方法调用时展开数组&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;前面我们已经说过了，在一个方法定义内的参数前面可以加一个星号，这样所有后面的参数都被放到了一个数组中，反过来，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;也支持调用的时候指定一个数组代替若干个参数。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;在调用方法的时候，你可以展开一个数组，它的每个元素都将作为一个单独的参数使用。使用的时候，需要在这个作为参数的数组&lt;/span&gt;&lt;span lang="EN-US"&gt;(which must follow all the regular arguments)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;前面加一个星号。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def five(a, b, c, d, e)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"I was passed #{a} #{b} #{c} #{d} #{e}"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;five(1, 2, 3, 4, 5 ) &lt;span style=""&gt;&lt;/span&gt;=&gt; "I was passed 1 2 3 4 5"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;five(1, 2, 3, *['a', 'b']) &lt;span style=""&gt;&lt;/span&gt;=&gt; "I was passed 1 2 &lt;chmetcnv unitname="a" sourcevalue="3" hasspace="True" negative="False" numbertype="1" tcsc="0"&gt;3 a&lt;/chmetcnv&gt; b"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;five(*(10..14).to_a) &lt;span style=""&gt;&lt;/span&gt;=&gt; "I was passed 10 11 12 13 14"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UD"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;更加动态的块&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;我们已经看过了如何把一个方法和一个块联系起来。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;list_bones("aardvark") do |bone|&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 84pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# ...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;通常，这已经足够好了，我们可以给一个方法提供一个合适的块，而不必再方法中使用很多的&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;或者&lt;/span&gt;&lt;span lang="EN-US"&gt;while&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;等语句。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;但是有些时候，你需要更灵活一些，比如，下面的例子，如果选择&lt;/span&gt;&lt;span lang="EN-US"&gt;times&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，即输入&lt;/span&gt;&lt;span lang="EN-US"&gt;t&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，将会打印&lt;/span&gt;&lt;span lang="EN-US"&gt;2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;4&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;6&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;8&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;等等&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;代码不检查输入错误&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print "(t)imes or (p)lus: "&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;times = gets&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print "number: "&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;number = Integer(gets)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if times =~ /^t/&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts((1..10).collect {|n| n*number }.join(", "))&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts((1..10).collect {|n| n+number }.join(", "))&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;(t)imes or (p)lus: t&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;number: 2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;2, 4, 6, 8, 10, 12, 14, 16, 18, 20&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;虽然这样可以工作，但是不是很完美，事实上&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;语句的每个分枝是一样的代码。如果我们能用块来计算这些将会更好。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print "(t)imes or (p)lus: "&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;times = gets&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print "number: "&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;number = Integer(gets)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if times =~ /^t/&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;calc = lambda {|n| n*number }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;calc = lambda {|n| n+number }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts((1..10).collect(&amp;calc).join(", "))&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;(t)imes or (p)lus: t&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;number: 2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;2, 4, 6, 8, 10, 12, 14, 16, 18, 20&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;如果最后一个方法的最后一个参数以&lt;/span&gt;&lt;span lang="EN-US"&gt;"&amp;"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;开头，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;把它视为一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象，它被从参数列表中移除，并被转换成&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象传入与这个方法相关联的块内。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UE"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;哈希结构作为参数&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt; text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;一些语言支持关键字参数，即不按照参数的个数和位置来调用一个方法，而是以任意次序传递带有值的参数的名字。&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby1.8&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;没有关键字参数&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;谎言，本书的前一个版本说过它有，或许是在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby2.0&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。在这期间，人们使用哈希表来达到同样的效果。例如，我们可以考虑为我们的&lt;/span&gt;&lt;span lang="EN-US"&gt;SongList&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;添加更强大的名字搜索功能。&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Times-Roman;font-size:10;"  lang="EN-US" &gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class SongList&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def create_search(name, params)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# ...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;list.create_search("short jazz songs",&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 89.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 110.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;'genre' =&gt; "jazz",&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 110.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;'duration_less_than' =&gt; 270&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 94.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;第一个参数是查找的名称，第二个参数是一个包含搜索参数的&lt;/span&gt;&lt;span lang="EN-US"&gt;Hash&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;字面值。使用&lt;/span&gt;&lt;span lang="EN-US"&gt;hash&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;意味着我们可以模仿关键字：音乐流派是&lt;/span&gt;&lt;span lang="EN-US"&gt;jazz&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，时长小于&lt;/span&gt;&lt;span lang="EN-US"&gt;4.5&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;分钟。但是这个实现还不是太好，而且大括号中的内容很容易被误认为是与方法关联的块。所以，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;提供了一个快捷方式，你可以在方法的参数中指定键&lt;/span&gt;&lt;span lang="EN-US"&gt;=&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;值的结构，像普通的参数那样。这些键值对会被收集到单个&lt;/span&gt;&lt;span lang="EN-US"&gt;Hash&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中，并做为一个参数传递给方法。花括号则就不需要了。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;list.create_search('short jazz songs',&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 168pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;'genre' =&gt; 'jazz',&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 168pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;'duration_less_than' =&gt; 270)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;最后，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;习惯上你或许应使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Symbol&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;而不是字符串，因为&lt;/span&gt;&lt;span lang="EN-US"&gt;Symbol&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;会使你引用某些名字变得更清晰&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;list.create_search('short jazz songs',&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 120.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;:genre =&gt; :jazz,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 120.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;:duration_less_than =&gt; 270)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;写作风格良好的&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;程序典型地有很多方法，每个都相当小，所以当定义和使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;方法时应熟悉有效的操作。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28827285-115278439145951465?l=nucleusg.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/115278439145951465/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=28827285&amp;postID=115278439145951465' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278439145951465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278439145951465'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/2006/07/blog-post.html' title='第六章 深入方法'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11202605830313623292'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28827285.post-115278412504791911</id><published>2006-07-13T18:48:00.000+09:00</published><updated>2006-07-13T18:49:22.640+09:00</updated><title type='text'>第五章 标准类型(3-2)</title><content type='html'>&lt;div class="storytext"&gt;        &lt;p align="center"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;第五章 标准类型(3-2)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;a name="S3"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;范围&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;    范围无处不在：从一月到十二月，&lt;/span&gt;&lt;span lang="EN-US"&gt;0&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;到&lt;/span&gt;&lt;span lang="EN-US"&gt;9&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，半熟到完全煮熟，从第&lt;/span&gt;&lt;span lang="EN-US"&gt;50&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;行到第&lt;/span&gt;&lt;span lang="EN-US"&gt;67&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;行等等。如果&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;想要帮助我们很好的根据现实世界来建模，它似乎自然也支持这些范围。事实上，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;支持的更好：它实际上使用范围来实现三种分离特征：序列，条件，和间隔。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;a name="S3"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;范围&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;范围无处不在：从一月到十二月，&lt;/span&gt;&lt;span lang="EN-US"&gt;0&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;到&lt;/span&gt;&lt;span lang="EN-US"&gt;9&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，半熟到完全煮熟，从第&lt;/span&gt;&lt;span lang="EN-US"&gt;50&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;行到第&lt;/span&gt;&lt;span lang="EN-US"&gt;67&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;行等等。如果&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;想要帮助我们很好的根据现实世界来建模，它似乎自然也支持这些范围。事实上，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;支持的更好：它实际上使用范围来实现三种分离特征：序列，条件，和间隔。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;a name="UB"&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;用作序列&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;首先或许对范围更自然的使用方式是表达一个序列。序列有起始点，终结点，和产生序列中下一个值的方式。&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中，这些序列使用&lt;/span&gt;&lt;span lang="EN-US"&gt;".."&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;"..."&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;范围操作符创建。两个点的形式创建一个包含范围，而三点的形式创建排除指定最高值的范围。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;1..10&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;'a'..'z'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;my_array = [ 1, 2, 3 ]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;0...my_array.length&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;不像早期的&lt;/span&gt;&lt;span lang="EN-US"&gt;Perl&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;那样，范围并不在内部表示为列表：次序&lt;/span&gt;&lt;span lang="EN-US"&gt;1..100000&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;被存为包含对两个&lt;/span&gt;&lt;span lang="EN-US"&gt;Fixnum&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象的引用的&lt;/span&gt;&lt;span lang="EN-US"&gt;Range&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象。如果需要，你可以使用&lt;/span&gt;&lt;span lang="EN-US"&gt;to_a&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;把范围转换成数组。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;(1..10).to_a &lt;span style=""&gt;      &lt;/span&gt;! [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;('bar'..'bat').to_a &lt;span style=""&gt;  &lt;/span&gt;! ["bar", "bas", "bat"]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style=";font-family:Times-Roman;font-size:10;"  lang="EN-US" &gt;&lt;span style="font-size:130%;"&gt;Ranges implement methods that let you iterate over them and test their contents in a&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style=";font-family:Times-Roman;font-size:10;"  lang="EN-US" &gt;&lt;span style="font-size:130%;"&gt;variety of ways.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ranges&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;实现的方法可以让你以多种方式对其进行迭代，测试它们的内容。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;digits = 0..9&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;digits.include?(5)&lt;span style=""&gt;  &lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;! true&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;digits.min &lt;span style=""&gt;        &lt;/span&gt;! 0&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;digits.max &lt;span style=""&gt;        &lt;/span&gt;! 9&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;digits.reject {|i| i &lt; style=""&gt;       &lt;/span&gt;! [5, 6, 7, 8, 9]&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;digits.each {|digit| dial(digit) } &lt;span style=""&gt; &lt;/span&gt;! 0..9&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;到现在我们展示了字符串和数字的范围。但是，就像你对面向对象的语言期望的，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;可以基于我们定义的对象来创建范围。唯一的限制是，这个对象必须对能返回序列内下一个对象的&lt;/span&gt;&lt;span lang="EN-US"&gt;succ&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;方法的响应，以及这个对象必须是可使用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;=&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来比较的。有时候调用太空飞船样的操作符，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;=&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来比较两个值，依赖于第一个值是否小于，等于，或大于第二个值，来返回&lt;/span&gt;&lt;span lang="EN-US"&gt;-1, 0, &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;+1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;这儿是个简单的类，它表示由&lt;/span&gt;&lt;span lang="EN-US"&gt;"#"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;符号表示的行。我们可能想使用它作为自动点唱机音量控制的基于文本的版本。&lt;/span&gt;&lt;span style=""&gt; &lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class VU&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;include Comparable&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;attr :volume&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def initialize(volume) # 0..9&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@volume = volume&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def inspect&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;'#' * @volume&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;# &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对范围的支持&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def &lt;=&gt;(other)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;self.volume &lt;=&gt; other.volume&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def succ&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;raise(IndexError, "Volume too big") if @volume &gt;= 9&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;VU.new(@volume.succ)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;因为们的&lt;/span&gt;&lt;span lang="EN-US"&gt;VU&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类实现了&lt;/span&gt;&lt;span lang="EN-US"&gt;succ&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;=&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，它可以使用范围了。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;medium_volume = VU.new(4)..VU.new(7)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;medium_volume.to_a &lt;span style=""&gt;     &lt;/span&gt;! [####, #####, ######, #######]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;medium_volume.include?(VU.new(3)) &lt;span style=""&gt;   &lt;/span&gt;! false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;我们可以创建一个&lt;/span&gt;&lt;span lang="EN-US"&gt;VU&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的&lt;/span&gt;&lt;span lang="EN-US"&gt;range&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来测试一下：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;medium = VU.new(4)..VU.new(7) &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;medium.to_a &lt;span style=""&gt; &lt;/span&gt;}} [####, #####, ######, #######] &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;medium.include?(VU.new(3)) &lt;span style=""&gt; &lt;/span&gt;}}&lt;span style=""&gt;  &lt;/span&gt;false &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;a name="UC"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;用做条件&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;除了表示序列外，范围也被用于做条件表达式。这儿，它们的行为像一种开关&lt;/span&gt;&lt;span lang="EN-US"&gt;—&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;当范围的第一部分条件变成&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;时，它们开户。当第二部分条件变成&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;时，它们关闭。比如，下面代码片断印出来自标准输入的行集，每个行集的第一行包含单词&lt;/span&gt;&lt;span lang="EN-US"&gt;start&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;最后一行包含单词&lt;/span&gt;&lt;span lang="EN-US"&gt;end&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;while line = gets&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts line if line =~ /start/ .. line =~ /end/&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;在背后，范围持有测试的每个状态轨迹。我们将在&lt;/span&gt;&lt;span lang="EN-US"&gt;94&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;页看到些例子。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;旧版本中，范围很少被用于&lt;/span&gt;&lt;span lang="EN-US"&gt;if&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;while&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;等相似的语句中。例如，你可以用下面代码片断重写上面的例子&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;while gets&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print if /start/../end/&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;这不被支持。不幸的是，没有错误提示；每次测试也会成功。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;a name="UD"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;用做间隔&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;范围的最后一个用处是用做间隔测试：看是否有值落在由范围表示的间隔之内。我们使用&lt;/span&gt;&lt;span lang="EN-US"&gt;===&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来做，它是&lt;/span&gt;&lt;span lang="EN-US"&gt;case&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;等同操作符。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;a name="S4"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;(1..10) === 5 &lt;span style=""&gt;  &lt;/span&gt;! true&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;(1..10) === 15 &lt;span style=""&gt; &lt;/span&gt;! false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;(1..10) === 3.14159&lt;span style=""&gt;  &lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;! true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;('a'..'j') === 'c' &lt;span style=""&gt;   &lt;/span&gt;! true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;('a'..'j') === 'z' &lt;span style=""&gt;   &lt;/span&gt;! false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;case&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;表达式的例子在&lt;/span&gt;&lt;span lang="EN-US"&gt;92&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;页给出。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style=""&gt;&lt;span style=";font-family:Times-Roman;font-size:10;color:black;"   lang="EN-US" &gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;正则表达式&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;回到&lt;/span&gt;&lt;span lang="EN-US"&gt;59&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;页，当我们从一个文件里创建歌曲列表时，我们用了正则表达式去匹配输入文件里的界定符字段。我们声明了表达式&lt;/span&gt;&lt;span lang="EN-US"&gt; line.split(/s*|s*)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来匹配一个由任意空格包围的小竖线。让我们更祥细地阐明正则表达式来看看为什么这个声明是正确的。&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;正则表达式用来匹配与字符串对应的模式。&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;提供了对方便简洁的模式匹配和替换的内建支持。这一部分，我们将介绍正则表达式的使用重要特征。这儿有些细节我们不会涉及：你可以参考第&lt;/span&gt;&lt;span lang="EN-US"&gt;309&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;页取得更多信息。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;正则表达式是类型&lt;/span&gt;&lt;span lang="EN-US"&gt;Regexp&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的对象。它们可以显式地用构造函数或使用字符值形式&lt;/span&gt;&lt;span lang="EN-US"&gt;/pattern/ &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;%r{pattern}&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来创建。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = Regexp.new('^s*[az]')&lt;span style=""&gt;   &lt;/span&gt;! /^s*[az]/&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b = /^s*[az]/&lt;span style=""&gt;   &lt;/span&gt;! /^s*[az]/&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;c = %r{^s*[az]}&lt;span style=""&gt;   &lt;/span&gt;! /^s*[az]/&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;一旦你有了正则表达式对象，你可以对一个字符串进行匹配，使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Regexp#match(string) &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;或者用匹配操作符&lt;/span&gt;&lt;span lang="EN-US"&gt;=~&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;（确定匹配）及&lt;/span&gt;&lt;span lang="EN-US"&gt; !~&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;（否定匹配）。匹配操作定义用于字符串和&lt;/span&gt;&lt;span lang="EN-US"&gt;Regexp&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象。至少匹配操作符的一个操作数必须是个正则表达式。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的前一个版本中，两都都可以是字符串，在这种情况，第二个操作数在后台被偷偷转换为正则表达式。&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;name = "Fats Waller"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;name =~ /a/ &lt;span style=""&gt;  &lt;/span&gt;! 1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;name =~ /z/ &lt;span style=""&gt;  &lt;/span&gt;! nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;/a/ =~ name&lt;span style=""&gt;  &lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;! 1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;匹配出现时，匹配操作符返回字符位置。&lt;/span&gt; &lt;span style="font-family:宋体;"&gt;它们也有个副作用，设置&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;加载的变量。&lt;/span&gt;&lt;span lang="EN-US"&gt;$&amp;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;接受模式匹配成功的那部分字符，&lt;/span&gt;&lt;span lang="EN-US"&gt;$`(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;键盘&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;左边那个键）接受模式匹配成功的字符串前面的那一部分字符串，&lt;/span&gt;&lt;span lang="EN-US"&gt;$'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;接受模式匹配成功的字符串后面的那部分字符串。我们可以用这个来编写一个函数，&lt;/span&gt;&lt;span lang="EN-US"&gt;show_regexp&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，它阐明了一个特殊的模式匹配例子：&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def show_regexp(a, re)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if a =~ re&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"#{$`}&lt;&lt;#{$&amp;}&gt;&gt;#{$'}"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"no match"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp('very interesting', /t/)&lt;span style=""&gt;   &lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;! very in&lt;&lt;t&gt;&gt;eresting&lt;/t&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp('Fats Waller', /a/)&lt;span style=""&gt;      &lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;! F&lt;&lt;a&gt;&gt;ts Waller&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;a&gt;show_regexp('Fats Waller', /ll/)&lt;span style=""&gt;      &lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;! Fats Wa&lt;&lt;ll&gt;&gt;er&lt;/ll&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;a&gt;show_regexp('Fats Waller', /z/) &lt;span style=""&gt;      &lt;/span&gt;! no match&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;这个匹配也设置了&lt;/a&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a&gt;Ruby&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;的全局线程变量&lt;/a&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a&gt; $~ &lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;和&lt;/a&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a&gt; $1 &lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;到&lt;/a&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a&gt; $9&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;。变量&lt;/a&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a&gt; $~ &lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;是一个&lt;/a&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a&gt;MatchData&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;对象（在&lt;/a&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a&gt;516&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;页开始部分有描述），它保存了所有关于这个匹配的信息。&lt;/a&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a&gt;$1&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;等等持有匹配的部分变量。我们稍后讨论它们。如果有人看见这些像&lt;/a&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a&gt;Perl&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;a&gt;语言的变量名感到害怕，不要着急，这章后面还有好消息。&lt;/a&gt;&lt;/span&gt;&lt;a&gt; &lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;a&gt; &lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;a name="UE"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;模式&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;每个正则表达式都有一个模式，用来和一个字符串做匹配。&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;在一个模式中，除了&lt;/span&gt;&lt;span lang="EN-US"&gt;., |, (, ), [, {, +, , ^, $, *&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt; ? &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;之外的字符都是和它本身匹配。&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp('kangaroo', /angar/) &lt;span style=""&gt;  &lt;/span&gt;=&gt; k&lt;&lt;angar&gt;&gt;oo&lt;/angar&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp('!@%&amp;_=+',/%&amp;amp;/) &lt;span style=""&gt;  &lt;/span&gt;=&gt; !@&lt;&lt;%&amp;&gt;&gt;_=+&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;如果你想在这些特殊字符字面值上匹配一个字符，在它前面加一个&lt;/span&gt;&lt;span lang="EN-US"&gt;''&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。这解释了我们用在分离那个歌曲列表文件时用的一个正则表达式的一部分，&lt;/span&gt;&lt;span lang="EN-US"&gt;/s*|s*/&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;span lang="EN-US"&gt;'|'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;表示匹配一个&lt;/span&gt;&lt;span lang="EN-US"&gt;'|'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，没有那个反斜杠，&lt;/span&gt;&lt;span lang="EN-US"&gt;'|'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;代表着选择（我们会在后面描述）。&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp('yes | no', /|/) &lt;span style=""&gt; &lt;/span&gt;=&gt; yes &lt;&lt;|&gt;&gt; no&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp('yes (no)', /(no)/) &lt;span style=""&gt; &lt;/span&gt;=&gt; yes &lt;&lt;(no)&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp('are you sure?', /e?/) &lt;span style=""&gt; &lt;/span&gt;=&gt; are you sur&lt;&lt;e?&gt;&gt;&lt;/e?&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt; text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;反斜杠后跟一个数字字符用来引进一个特殊的匹配构造，我们会在后面介绍它。另外，一个正则表达式可以包含&lt;/span&gt;&lt;span lang="EN-US"&gt;#{...}&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;展开式&lt;/span&gt;&lt;span style=";font-family:宋体;font-size:12;"  &gt;。 &lt;/span&gt;&lt;span style=";font-family:Times-Roman;font-size:10;"  lang="EN-US" &gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style=";font-family:宋体;font-size:12;"  lang="EN-US" &gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;a name="UF"&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;span style="font-size:130%;"&gt;Anchors&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;缺省情况下，一个正则表达式将试图查找字符串中第一个匹配的模式。要在字符串&lt;/span&gt;&lt;span lang="EN-US"&gt;"Mississippi"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中匹配&lt;/span&gt;&lt;span lang="EN-US"&gt; /iss/ &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，它会找到那个靠近开始位置的哪个子串&lt;/span&gt;&lt;span lang="EN-US"&gt;"iss"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。但是当你想自己指定从头部或者末尾开始匹配时要怎么设置呢？&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;模式&lt;/span&gt;&lt;span lang="EN-US"&gt; ^ &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt; $ &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;分别匹配一行字符的开始和结束。它们经常用来指定一个模式匹配的方向：比如，&lt;/span&gt;&lt;span lang="EN-US"&gt;/^option/&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;只与在一行文本开始处出现的单词&lt;/span&gt;&lt;span lang="EN-US"&gt;'option'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;匹配。字符序列&lt;/span&gt;&lt;span lang="EN-US"&gt; A &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和一个字符串的开始匹配，&lt;/span&gt;&lt;span lang="EN-US"&gt;z &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt; Z &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和一个字符串的结束匹配。（事实上，&lt;/span&gt;&lt;span lang="EN-US"&gt;Z &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和一个以&lt;/span&gt;&lt;span lang="EN-US"&gt;"n"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;结尾的字符串的结束匹配，这种情况下，它从&lt;/span&gt;&lt;span lang="EN-US"&gt;'n'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;前面开始匹配）。&lt;/span&gt;&lt;span style=""&gt; &lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp("this isnthe time", /^the/) &lt;span style=""&gt; &lt;/span&gt;=&gt; this isn&lt;&lt;the&gt;&gt; time&lt;/the&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp("this isnthe time", /is$/) &lt;span style=""&gt; &lt;/span&gt;=&gt; this &lt;&lt;is&gt;&gt;nthe time&lt;/is&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp("this isnthe time", /Athis/) &lt;span style=""&gt; &lt;/span&gt;=&gt; &lt;&lt;this&gt;&gt; isnthe time&lt;/this&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp("this isnthe time", /Athe/) &lt;span style=""&gt; &lt;/span&gt;=&gt; no match&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;类似的，模式&lt;/span&gt;&lt;span lang="EN-US"&gt; b &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt; B &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;分别和单词边界和非单词边界匹配。构成单词的字符有字母，数字和下划线。&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp("this isnthe time", /bis/) &lt;span style=""&gt; &lt;/span&gt;=&gt; this &lt;&lt;is&gt;&gt;nthe time&lt;/is&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp("this isnthe time", /Bis/) &lt;span style=""&gt; &lt;/span&gt;=&gt; th&lt;&lt;is&gt;&gt; isnthe time&lt;/is&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;a name="UG"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;字符类&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;（&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;character class&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;）&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;字符类是在方括号之间的一系列字符：&lt;/span&gt;&lt;span lang="EN-US"&gt;[characters]&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;匹配方括号里面的任何单个字符。&lt;/span&gt;&lt;span lang="EN-US"&gt;[aeiou]&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;会匹配一个元音，&lt;/span&gt;&lt;span lang="EN-US"&gt;[,.:;!?]&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;匹配标点符号，等等。那些重要的特殊正则表达式字符（&lt;/span&gt;&lt;span lang="EN-US"&gt;.|()[{+^$*?&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;）在方括号里面会失去匹配作用。但是普通的转义字符仍然起作用，所以，&lt;/span&gt;&lt;span lang="EN-US"&gt;b&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;代表退格键，&lt;/span&gt;&lt;span lang="EN-US"&gt;n&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是换行符（见&lt;/span&gt;&lt;span lang="EN-US"&gt;306&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;页表&lt;/span&gt;&lt;span lang="EN-US"&gt;22.2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;）。另外，你可以用下页的表&lt;/span&gt;&lt;span lang="EN-US"&gt;5.1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的缩写，所以&lt;/span&gt; &lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;例如&lt;/span&gt;&lt;span lang="EN-US"&gt;)s &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;表示空白符，不仅仅是一个字面上的空格。&lt;/span&gt; &lt;span lang="EN-US"&gt;The POSIX character classes in the second half of the&lt;span style=""&gt;  &lt;/span&gt;table correspond to the ctype(3) macros of the same names.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;show_regexp('Price $12.', /[aeiou]/) &lt;span style=""&gt; &lt;/span&gt;=&gt; Pr&lt;&lt;i&gt;&gt;ce $12.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;show_regexp('Price $12.', /[s]/) &lt;span style=""&gt; &lt;/span&gt;=&gt; Price&lt;&lt; &gt;&gt;$12.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;show_regexp('Price $12.', /[[:digit:]]/) &lt;span style=""&gt; &lt;/span&gt;=&gt; Price $&lt;&lt;1&gt;&gt;2.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;show_regexp('Price $12.', /[[:space:]]/) &lt;span style=""&gt; &lt;/span&gt;=&gt; Price&lt;&lt; &gt;&gt;$12.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;show_regexp('Price $12.', /[[:punct:]aeiou]/) &lt;span style=""&gt; &lt;/span&gt;=&gt; Pr&lt;&lt;i&gt;&gt;ce $12.&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;在方括号里面，序列&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt; c1-c2 &lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;表示包括在&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt;c1&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;到&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt;c2&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;之间的字符。&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt; &lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 71.9pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;i&gt;&lt;i&gt; &lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt;a = 'see [Design Patternspage 123]'&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 71.9pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /[AF]/)&lt;span style=""&gt;  &lt;/span&gt;=&gt; see [&lt;&lt;d&gt;&gt;esign Patternspage 123]&lt;/d&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 71.9pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /[AFaf]/) =&gt; s&lt;&lt;e&gt;&gt;e [Design Patternspage 123]&lt;/e&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 71.9pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /[09]/)&lt;span style=""&gt;  &lt;/span&gt;=&gt; see [Design Patternspage &lt;&lt;1&gt;&gt;23]&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 71.9pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /[09][09]/) =&gt; see [Design Patternspage &lt;&lt;12&gt;&gt;3]&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;如果你想包含字符类内的方括号&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt; ] &lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;和&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt; - &lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;的话，它们必须出现在开始。在左方括号后直接跟个&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt;^&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;来否定一个字符类：&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt;[^a-z]&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;匹配任何不是小写的字母。&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;a = 'see [Design Patternspage 123]'&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /[]]/) &lt;span style=""&gt; &lt;/span&gt;=&gt; see [Design Patternspage 123&lt;&lt;]&gt;&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /[]/)&lt;span style=""&gt;  &lt;/span&gt;=&gt; see [Design Patterns&lt;&lt;&gt;&gt; page 123]&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /[^az]/) =&gt; see&lt;&lt; &gt;&gt;[Design Patternspage 123]&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /[^azs]/) &lt;span style=""&gt; &lt;/span&gt;=&gt; see &lt;&lt;[&gt;&gt;Design Patternspage 123]&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;有些字符类使用频繁，&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;i&gt;&lt;i&gt;Ruby&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;为它们提供了缩写。这些缩写列在下一页的表&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;i&gt;&lt;i&gt;5.1&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;中&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;i&gt;&lt;i&gt;—&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;它们即可以用在方括号中可以用在模式中。&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp('It costs $12.', /s/) =&gt; It&lt;&lt; &gt;&gt;costs $12.&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp('It costs $12.', /d/) &lt;span style=""&gt; &lt;/span&gt;=&gt; It costs $&lt;&lt;1&gt;&gt;2.&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;最后，一个句点&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt;"."&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;i&gt;&lt;i&gt;出现在方括号外面表示除了换行符以外的任何字符（尽管在多行模式下它也匹配一个换行符）。&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;i&gt;&lt;i&gt; &lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;a = 'It costs $12.'&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /c.s/) =&gt; It &lt;&lt;cos&gt;&gt;ts $12.&lt;/cos&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /./) &lt;span style=""&gt;  &lt;/span&gt;=&gt; &lt;&lt;i&gt;&gt;t costs $12.&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;show_regexp(a, /./) &lt;span style=""&gt; &lt;/span&gt;=&gt; It costs $12&lt;&lt;.&gt;&gt;&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt; &lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 44.95pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;Table 5.1. Character class abbreviations&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 44.95pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;-------------------------------------------------------------------------------&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 45.1pt; text-align: left;" align="left"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Sequence&lt;span style=""&gt;                         &lt;/span&gt;As [ . . . ]&lt;span style=""&gt;     &lt;/span&gt;&lt;span style=""&gt;   &lt;/span&gt;Meaning&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;      &lt;/span&gt;------------------------------------------------------------------------------------&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;d&lt;span style=""&gt;                  &lt;/span&gt;[0-9]&lt;span style=""&gt;                          &lt;/span&gt;Digit character&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;D&lt;span style=""&gt;                  &lt;/span&gt;[^0-9]&lt;span style=""&gt;                        &lt;/span&gt;Any character except a digit&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;s&lt;span style=""&gt;                   &lt;/span&gt;[strnf]&lt;span style=""&gt;                   &lt;/span&gt;Whitespace character&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;S&lt;span style=""&gt;                  &lt;/span&gt;[^strnf]&lt;span style=""&gt;                 &lt;/span&gt;Any character except whitespace&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;w&lt;span style=""&gt;                 &lt;/span&gt;[A-Za-z0-9_]&lt;span style=""&gt;              &lt;/span&gt;Word character&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;W&lt;span style=""&gt;                 &lt;/span&gt;[^A-Za-z0-9_]&lt;span style=""&gt;             &lt;/span&gt;Any character except a word character&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 44.95pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;------------------------------------------------------------------------------&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 44.95pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;                &lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt; &lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 44.95pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt; &lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;           &lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;POSIX&lt;span style=""&gt;                &lt;/span&gt;Character Classes&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;&lt;b style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;------------------------------------------------------------------------------&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:alnum:] &lt;span style=""&gt;             &lt;/span&gt;Alphanumeric&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:alpha:]&lt;span style=""&gt;                &lt;/span&gt;Uppercase or lowercase letter&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:blank:]&lt;span style=""&gt;                &lt;/span&gt;Blank and tab&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:cntrl:]&lt;span style=""&gt;                 &lt;/span&gt;Control characters (at least 0x00–0x&lt;chmetcnv unitname="F" sourcevalue="1" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;1f&lt;/chmetcnv&gt;, 0x&lt;chmetcnv unitname="F" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;7f&lt;/chmetcnv&gt;)&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:digit:]&lt;span style=""&gt;                 &lt;/span&gt;Digit&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:graph:]&lt;span style=""&gt;               &lt;/span&gt;Printable character excluding space&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:lower:]&lt;span style=""&gt;               &lt;/span&gt;Lowercase letter&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:print:]&lt;span style=""&gt;                 &lt;/span&gt;Any printable character (including space)&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:punct:]&lt;span style=""&gt;               &lt;/span&gt;Printable character excluding space and alphanumeric&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:space:]&lt;span style=""&gt;               &lt;/span&gt;Whitespace (same as s)&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:upper:]&lt;span style=""&gt;               &lt;/span&gt;Uppercase letter&lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt;[:xdigit:]&lt;span style=""&gt;               &lt;/span&gt;Hex digi           &lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;i&gt;&lt;i&gt;&lt;i&gt; &lt;/i&gt;&lt;/i&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28827285-115278412504791911?l=nucleusg.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/115278412504791911/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=28827285&amp;postID=115278412504791911' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278412504791911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278412504791911'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/2006/07/3-2_13.html' title='第五章 标准类型(3-2)'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11202605830313623292'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28827285.post-115278401997274162</id><published>2006-07-13T18:46:00.000+09:00</published><updated>2006-07-13T18:47:46.186+09:00</updated><title type='text'>第五章 标准类型(3-1)</title><content type='html'>&lt;span style="font-family:宋体;"&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;" align="center"&gt;&lt;span style="font-family:宋体;"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;第五章 标准类型(3-1)&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;到现在我们已经实现了我们那点唱机的一部分代码，但是我们还是很粗心的。我们看到了数组，哈希，过程对象&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Proc&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，但我们还没有涉及到&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中其他的基本数据类型：数字，字符串，范围（&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;ranges&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;），正则表达式。下面我们就要花些时间来看看这些基本构建材料。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S1"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;数字型&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;支持整型和浮点型两种数字类型。整型可以是任意长度（最大值由你机器的内存大小决定）。整型带有一定范围（通常是&lt;/span&gt;&lt;span lang="EN-US"&gt;-230 to 230-1 or -262 to 262-1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;）在内部由二进制方式表示，整型是类&lt;/span&gt;&lt;span lang="EN-US"&gt;Fixnum&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的对象。大小超过这个范围的整数由&lt;/span&gt;&lt;span lang="EN-US"&gt;Bignum&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类的对象存储&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;当前做为一个可变长度的整数集实现&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。如果&lt;/span&gt;&lt;span lang="EN-US"&gt;Fixnum&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;计算之后结果超出范围，自动转换为&lt;/span&gt;&lt;span lang="EN-US"&gt;Bignum&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;在两者之间自动转换，对用户来说是透明的。&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Times-Roman;font-size:10;"  lang="EN-US" &gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;num = 81&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;6.times do&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 37.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts "#{num.class}: #{num}"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 37.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;num *= num&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Fixnum: 81&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Fixnum: 6561&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Fixnum: 43046721&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Bignum: 1853020188851841&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Bignum: 3433683820292512484657849089281&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 27pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Bignum: 11790184577738583171520872861412518665678211592275841109096961&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;你也可以使用一个可选的引导符号来写整数，一个可选的基本的指示符&lt;/span&gt;&lt;span lang="EN-US"&gt;(0&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;用于八进制，&lt;/span&gt;&lt;span lang="EN-US"&gt;0d&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;用于十进制&lt;/span&gt;&lt;span lang="EN-US"&gt;[&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;缺省的&lt;/span&gt;&lt;span lang="EN-US"&gt;]&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;0x&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;用于十六进制&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，跟随在适当基数数字字符串后面。数字字符串内的下划线被忽略&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;一些人使用它们来代替大数字的逗号&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;123456 =&gt; 123456 # Fixnum&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;0d123456 =&gt; 123456 # Fixnum&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;123_456 =&gt; 123456 # Fixnum underscore ignored&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;543&lt;span style=""&gt; &lt;/span&gt;=&gt; 543&lt;span style=""&gt; &lt;/span&gt;# Fixnum negative number&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;0xaabb =&gt; 43707 # Fixnum hexadecimal&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;0377 =&gt; 255 # Fixnum octal&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;0b10_1010 =&gt; 42&lt;span style=""&gt; &lt;/span&gt;# Fixnum binary (negated)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;123_456_789_123_456_789 =&gt; 123456789123456789 # Bignum&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;控制字符通常可以由&lt;/span&gt;&lt;span lang="EN-US"&gt;?Cx&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;与&lt;/span&gt;&lt;span lang="EN-US"&gt;?cx(x&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的控制版本是&lt;/span&gt;&lt;span lang="EN-US"&gt;x &amp; 0x&lt;chmetcnv unitname="F" sourcevalue="9" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;9f&lt;/chmetcnv&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;生成。&lt;/span&gt;&lt;span lang="EN-US"&gt;Metacharacters (x | 0x80)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;可以使用&lt;/span&gt;&lt;span lang="EN-US"&gt;?Mx&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;生成。&lt;/span&gt;&lt;span lang="EN-US"&gt;Meta-Control&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;由&lt;/span&gt;&lt;span lang="EN-US"&gt;?MCx&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;生成。你可以使用序列&lt;/span&gt;&lt;span lang="EN-US"&gt;?&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来获取一个反斜线字符的值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;?a &lt;span style=""&gt;&lt;/span&gt;=&gt; 97 &lt;span style=""&gt;&lt;/span&gt;# ASCII character&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;?n &lt;span style=""&gt;&lt;/span&gt;=&gt; 10 &lt;span style=""&gt;&lt;/span&gt;# code for a newline (0x&lt;chmetcnv unitname="a" sourcevalue="0" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;0a&lt;/chmetcnv&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;?Ca&lt;span style=""&gt; &lt;/span&gt;=&gt; 1&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;# control a = ?A &amp; 0x&lt;chmetcnv unitname="F" sourcevalue="9" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;9f&lt;/chmetcnv&gt; = 0x01&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;?Ma&lt;span style=""&gt; &lt;/span&gt;=&gt; 225 &lt;span style=""&gt;&lt;/span&gt;# meta sets bit 7&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;?MCa&lt;span style=""&gt; &lt;/span&gt;=&gt; 129 &lt;span style=""&gt;&lt;/span&gt;# meta and control a&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;?C?&lt;span style=""&gt; &lt;/span&gt;=&gt; 127&lt;span style=""&gt; &lt;/span&gt;# delete character&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;一个带小数点或者带指数的数字字面值会转换成一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Float&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象，对应于本机操作系统构架的&lt;/span&gt;&lt;span lang="EN-US"&gt;double&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;数据类型。你必须在小数点后面加一个数字&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;如果你将&lt;/span&gt;&lt;span lang="EN-US"&gt;1.0e3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;写成&lt;/span&gt;&lt;span lang="EN-US"&gt;1.e3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;将会试图调用类&lt;/span&gt;&lt;span lang="EN-US"&gt;Fixnum&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中的方法&lt;/span&gt;&lt;span lang="EN-US"&gt;e3)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;所有数字都是对象，会响应一些消息（在&lt;/span&gt;&lt;span lang="EN-US"&gt;420, 463,466, 480&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;541&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;页会完整的描述）。所以不像（比如说）&lt;/span&gt;&lt;span lang="EN-US"&gt; C++&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，你会发现求一个数字的绝对值是这样写的&lt;/span&gt;&lt;span lang="EN-US"&gt; aNumber.abs&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，而不是&lt;/span&gt;&lt;span lang="EN-US"&gt;abs(aNumber)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;整数也支持一些有用的迭代器。我们已经看到过一个&lt;/span&gt;&lt;span lang="EN-US"&gt;:6.times&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;在前面的代码例子中。还有其他的比如&lt;/span&gt;&lt;span lang="EN-US"&gt; upto &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt; downto&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，用来在两个整数之间向上和向下迭代，类&lt;/span&gt;&lt;span lang="EN-US"&gt;Numeric&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;也提供了更通用的方法&lt;/span&gt;&lt;span lang="EN-US"&gt;step&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，它更像一个传统的&lt;/span&gt;&lt;span lang="EN-US"&gt; for &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;循环语句。&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;3.times { print "X " }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;1.upto(5) {|i| print i, " " }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;99.downto(95) {|i| print i, " " }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;50.step(80, 5) {|i| print i, " " }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;X X X 1 2 3 4 5 99 98 97 96 95 50 55 60 65 70 75 80&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;最后，给&lt;/span&gt;&lt;span lang="EN-US"&gt;Perl&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;使用者提供一个警告。只含有数字字符的字符串在表达式中使用时不会自动转换成数字。这最有可能在从文件里读取数字时引发错误。例如，我们可能想从文件的每行中找出两个数的和如&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;3 4&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;5 6&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;7 8&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;下面代码不会工作。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;some_file.each do |line|&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;v1, v2 = line.split # split line on spaces&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print v1 + v2, " "&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;34 56 78&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;问题就出在程序把输入当成字符串，而不是数字的。加号运算符把两个字符串连接，所以这就是我们看到的输出。要解决这个问题，我们可以使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Integer&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;将字符串转换成整数。&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;some_file.each do |line|&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;v1, v2 = line.split&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print Integer(v1) + Integer(v2), " "&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;7 11 15&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S2"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;字符串&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的字符串是简单的&lt;/span&gt;&lt;span lang="EN-US"&gt;8&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;位字节（&lt;/span&gt;&lt;span lang="EN-US"&gt;8-bit bytes&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;）序列。它们通常保存可打印字符序列，但是这不是必需的；一个字符串也可以保存二进制数据。字符串是类&lt;/span&gt;&lt;span lang="EN-US"&gt;String&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的对象。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;字符串通常用字符串字面值建立&lt;/span&gt;&lt;span lang="EN-US"&gt;---&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;两 个定界符内字符序列。因为二进制数据很难在程序代码里面表达，你可以在一个字符串字面值中使用各种转义序列。每个转义序列都会在程序编译的时候转换成相应 的二进制数值。字符串界定符的种类由完成的置换操作的程序决定。单引号内的字符串，两个连续的反斜线会被一个反斜杠取代，一个反斜杠后面跟一个单引号变成 一个单引号。&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;'escape using ""' ! escape using ""&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;'That's right' ! That's right&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;双引号字符串支持更多的转义序列。最常见的可能是&lt;/span&gt;&lt;span lang="EN-US"&gt;"n"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，新行字符。第&lt;/span&gt;&lt;span lang="EN-US"&gt;306&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;页的表&lt;/span&gt;&lt;span lang="EN-US"&gt;22.2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;给出了完整列表。另外，你可以用序列&lt;/span&gt;&lt;span lang="EN-US"&gt; #{ expr } &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来把任何的&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;代码的值置换到字符串中。如果代码只是个全局变量，类变量或者实例变量，你可以省略花括号。&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"Seconds/day: #{24*60*60}" &lt;span style=""&gt;&lt;/span&gt;! Seconds/day: 86400&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"#{'Ho! '*3}Merry Christmas!" &lt;span style=""&gt;&lt;/span&gt;! Ho! Ho! Ho! Merry Christmas!&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"This is line #$." &lt;span style=""&gt;&lt;/span&gt;! This is line 3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;以内插值替换的代码可以是一个或多个语句，不只是一个表达式。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts "now is #{ def the(a)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;'the ' + a&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 105pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 99.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;the('time')&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 78.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;} for all good coders..."&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;now is the time for all good coders...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;还有三种方法来构建字符串字面值：&lt;/span&gt;&lt;span lang="EN-US"&gt;%q, %Q&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和多行字符串的字面值&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;%q &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt; %Q&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;用来界定单引号和双引号字符串&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;你可以将&lt;/span&gt;&lt;span lang="EN-US"&gt;%q&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;想像为单薄的&lt;/span&gt;&lt;span lang="EN-US"&gt;’&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，而&lt;/span&gt;&lt;span lang="EN-US"&gt;%Q&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是厚重的&lt;/span&gt;&lt;span lang="EN-US"&gt;”)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;%q/general singlequoted string/ &lt;span style=""&gt;&lt;/span&gt;! general singlequoted string&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;%Q!general doublequoted string! &lt;span style=""&gt;&lt;/span&gt;! general doublequoted string&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;%Q{Seconds/day: #{24*60*60}} &lt;span style=""&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! Seconds/day: 86400&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;跟在&lt;/span&gt;&lt;span lang="EN-US"&gt;'q'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;或者&lt;/span&gt;&lt;span lang="EN-US"&gt;'Q'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;后面的字符是界定符。如果是左侧的方括号，圆括号，小括号或者小于符号&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style=";font-family:Times-Roman;font-size:12;"  lang="EN-US" &gt;“&lt;/span&gt;&lt;span style=";font-family:LuxiMono;font-size:12;"  lang="EN-US" &gt;[&lt;/span&gt;&lt;span style=";font-family:Times-Roman;font-size:12;"  lang="EN-US" &gt;”, “&lt;/span&gt;&lt;span style=";font-family:LuxiMono;font-size:12;"  lang="EN-US" &gt;{&lt;/span&gt;&lt;span style=";font-family:Times-Roman;font-size:12;"  lang="EN-US" &gt;”, “&lt;/span&gt;&lt;span style=";font-family:LuxiMono;font-size:12;"  lang="EN-US" &gt;(&lt;/span&gt;&lt;span style=";font-family:Times-Roman;font-size:12;"  lang="EN-US" &gt;”, “&lt;/span&gt;&lt;span style=";font-family:CMMI10;font-size:12;"  lang="EN-US" &gt;&lt;&lt;/span&gt;&lt;span style=";font-family:Times-Roman;font-size:12;"  lang="EN-US" &gt;”,&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，那么程序会一直读直到匹配的右侧被发现为止。否则，一直读取字符串直到下一个同样界定符出现的位置。界定符不可以是任何非字母非数字或多字节字符。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;最后，你可以使用一个多行字符串的字面值来构建字符串。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;string = &lt;&lt;end_of_string&gt;&lt;/end_of_string&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;The body of the string&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;is the input lines up to&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;one ending with the same&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;text that followed the '&lt;&lt;'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;END_OF_STRING&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;多行字符串字面值由包含在开始到一个由你在&lt;/span&gt;&lt;span lang="EN-US"&gt;'&lt;&lt;'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;后面指定的结束符之间的（但是不包括结束符）多行字符串组成。一般的，这个结束符必须在第一列开始。但是如果你在&lt;/span&gt;&lt;span lang="EN-US"&gt;'&lt;&lt;'&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;后面加一个减号，你就可以缩进结束符了。&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;print &lt;&lt;string1,&gt;&lt;&lt;string2&gt;&lt;/string2&gt;&lt;/string1,&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Concat&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;STRING1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 57.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;enate&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 57.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;STRING2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Concat&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;enate&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;注意这种情况下&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;没有去除字符串内容的前导空格。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UA"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;运用字符串&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;String&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;可能是最大的&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;内建类了，它有超过&lt;/span&gt;&lt;span lang="EN-US"&gt;75&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;个标准方法。我们不会在这里挨个介绍它们；函数库参考有它们完整的介绍。相反，让我们先来看看几个常用的字符串用法&lt;/span&gt;&lt;span lang="EN-US"&gt;---&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;在日常编程中我们经常会用到的。&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;让我们回头看看我们的点唱机。尽管它是被设计成联接到互联网上的，但是也保存了一些很流行的歌曲在本地硬盘上。这样，即使我们的网络连接出问题了，我们仍然能够服务我们的顾客。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;由于历史的原因（还有其他原因吗？），歌曲列表是以行的形式保存在一文本文件内。文件中的每行内容包含了歌曲，歌曲长度，演唱者和曲名，所有的字段都是用小竖线分隔开的。一个典型的文件如下：&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;/jazz/j00132.mp3 | 3:45 | Fats Waller | Ain't Misbehavin'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;/jazz/j00319.mp3 | 2:58 | Louis Armstrong | Wonderful World&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;/bgrass/bg0732.mp3| 4:09 | Strength in Numbers | Texas Red&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;:&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;:&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;: &lt;span style=""&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;观察一下数据，很明显在我们建立一些基于这个文件的&lt;/span&gt;&lt;span lang="EN-US"&gt;Song&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象之前，我们需要用&lt;/span&gt;&lt;span lang="EN-US"&gt;String&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;类的一些方法来展开和清理这些字段。至少，我们需要：&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: -21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span  lang="EN-US" style="font-family:Wingdings;"&gt;&lt;span style=""&gt;l&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;将行分解成字段，&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: -21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span  lang="EN-US" style="font-family:Wingdings;"&gt;&lt;span style=""&gt;&lt;font&gt;l&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;将时间从&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;MM:SS&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;格式转换成秒，然后&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: -21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span  lang="EN-US" style="font-family:Wingdings;"&gt;&lt;span style=""&gt;&lt;font&gt;&lt;font&gt;l&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;移除演唱者名字中额外空格。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;我们的第一个任务是要把每行分解成字段，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;a href="http://www.ruby-cn.org/book/ProgrammingRuby/ref_c_string.html#String.split"&gt;&lt;span style="text-decoration: none;"&gt;String#split &lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;方法是最适合的了。在这里，我们传递给&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;split&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;方法一个正则表达式，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;/s*|s*/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;split&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;会用找到有任意空格的竖线将行分解成记号，还有，因为从文件里读取的行后面跟了一个换行符，在我们用&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;split&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;方法前，我们可以使用&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;a href="http://www.ruby-cn.org/book/ProgrammingRuby/ref_c_string.html#String.chomp"&gt;&lt;span style="text-decoration: none;"&gt;String#chomp &lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;来把换行符去掉。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;File.open("songdata") do |song_file|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;songs = SongList.new&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;song_file.each do |line|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 57.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;file, length, name, title = line.chomp.split(/s*|s*/)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 57.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;songs.append(Song.new(title, name, length))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;puts songs[1]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Song: Wonderful WorldLouis&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Armstrong (2:58)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;不幸的是，那个创建原始文件的人在敲入演唱者名字的时候是按列敲的，有些名字里面可能包含额外的空格。这样那些名字在我们极好的，高科技的，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;24&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;小时运行的显示板上显示会很难看。我们必须去掉那些额外的空格才能继续我们的工作。有很多方法来做这个工作，但是最简单的可能是用&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;a href="http://www.ruby-cn.org/book/ProgrammingRuby/ref_c_string.html#String.squeeze"&gt;&lt;span style="text-decoration: none;"&gt;String#squeeze &lt;/span&gt;&lt;/a&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;它会去除重复的字符。我们在这里使用这个方法的&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; squeeze! &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;格式，它会改变适当位置的字符串。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;File.open("songdata") do |song_file|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;songs = SongList.new&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;song_file.each do |line|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;file, length, name, title = line.chomp.split(/s*|s*/)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;name.squeeze!(" ")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;songs.append(Song.new(title, name, length))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;puts songs[1]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Song: Wonderful WorldLouis Armstrong (2:58)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;最后，还有一个小问题&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;---&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;时间的格式问题：文件说&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; 2:58&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;，我们想要用秒数来表示，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;178&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;秒。我们可以再次使用&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; split &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;函数，把用冒号分隔的两个字段分开。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;mins, secs = length.split(/:/)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;相反，我们将使用一个相关方法。与&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;split&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;相似的&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;a href="http://www.ruby-cn.org/book/ProgrammingRuby/ref_c_string.html#String.scan"&gt;&lt;span style="text-decoration: none;"&gt;String#scan&lt;/span&gt;&lt;span style="text-decoration: none;font-family:宋体;"  lang="EN-US"&gt;&lt;span lang="EN-US"&gt;，&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;它以模式为基础分割字符串。但是，与&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;split&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;不同，用&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;scan&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;允许你指定用来匹配字段的模式。在这个例子中，我们想为分字段和秒字段匹配一个或多个数字。用于一个或多个数字的模式是&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; /d+/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;File.open("songdata") do |song_file|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;songs = SongList.new&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;song_file.each do |line|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;file, length, name, title = line.chomp.split(/s*|s*/)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;name.squeeze!(" ")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;mins, secs = length.scan(/d+/)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;songs.append(Song.new(title, name, mins.to_i*60+secs.to_i))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;puts songs[1]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Song: Wonderful WorldLouis Armstrong (178)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;我们的点唱机有关键字搜索的能力。给一个歌曲名或者演唱者姓名中的单词，它能够列出所有匹配的歌曲。比如，敲进&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;"fats"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;，它可能列出&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; Fats Domino, Fats Navarro, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;和&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Fats Waller&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;的歌曲。例如，我们通过建立一个索引类来实现这个功能。给它一个对象和一些字符串，它会索引出那个对象里所有包含在字符串里的单词（有两个或者多个字符的）。这将会阐明&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;类的更多方法。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;class WordIndex&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;def initialize&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;@index = {}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;def add_to_index(obj, *phrases)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;phrases.each do |phrase|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;phrase.scan(/w[w']+/) do |word| &lt;span style=""&gt;&lt;/span&gt;#&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;提取单词&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;word.downcase!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;@index[word] = [] if @index[word].nil?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 73.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;@index[word].push(obj)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;def lookup(word)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;@index[word.downcase]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;a href="http://www.ruby-cn.org/book/ProgrammingRuby/ref_c_string.html#String.scan"&gt;&lt;span style="text-decoration: none;"&gt;&lt;span style="font-size:130%;"&gt;String#scan&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;方法能从匹配正则表达式的字符串中抽取元素。在这个例子里面模式&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;“w[-w']+”&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;能匹配任何能出现在单词里的字符，后面跟一个或多个在方括号里指定的东东（一个小横线，另一个单词字符或者一个单引号）。我们会在&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;64&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;页更详细地介绍正则表达式。要让我们的搜索大小写不敏感，我们把我们提取出来的单词和传进来用做查找关键字的单词转化成小写。注意在第一个&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; downcase! &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;方法后面的感叹号。就像以前我们使用的&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; squeeze! &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;方法一样，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;"!"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;是一个标识来表明方法会在适当位置修改被调，在这里表示把字符串变成小写。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;[&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;这段代码里面有一个&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Bug, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;歌曲&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;"Gone, Gone, Gone"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;会被索引三次。你能想一个方法修正它吗？&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;] &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;我们来扩展一下我们的&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; SongList &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;类，让它能够在歌曲加进来的时候索引它们，然后加一个用一个字符串查找歌曲的方法。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;class SongList&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;def initialize&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;@songs = Array.new&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;@index = WordIndex.new&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;def append(song)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;@songs.push(song)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;@index.add_to_index(song, song.name, song.artist)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;self&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;def lookup(word)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;@index.lookup(word)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;最后，我们来测试一下：&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;songs = SongList.new&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;song_file.each do |line|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;file, length, name, title = line.chomp.split(/s*|s*/)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;name.squeeze!(" ")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;mins, secs = length.scan(/d+/)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;songs.append(Song.new(title, name, mins.to_i*60+secs.to_i))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;puts songs.lookup("Fats")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;puts songs.lookup("ain't")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;puts songs.lookup("RED")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;puts songs.lookup("WoRlD")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Song: Ain't Misbehavin'Fats&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Waller (225)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Song: Ain't Misbehavin'Fats&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Waller (225)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Song: &lt;place&gt;&lt;state&gt;Texas&lt;/state&gt;&lt;/place&gt; RedStrength&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;in Numbers (249)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Song: Wonderful WorldLouis&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;Armstrong (178)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;前面代码中，&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;lookup&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;方法返回匹配的数组。当我们传递数组给&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;puts&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;方法时，它依次简单地印出每个带有新行的元素。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;我们可以再花&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;50&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;页的篇幅来介绍&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; String &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;类里面的所有方法。但是，现在还是让我们继续来学习一个简单的数据类型：范围。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:宋体;font-size:12;"  &gt;&lt;span style="font-size:130%;"&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;　&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font&gt;&lt;font&gt;&lt;font&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28827285-115278401997274162?l=nucleusg.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/115278401997274162/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=28827285&amp;postID=115278401997274162' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278401997274162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278401997274162'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/2006/07/3-1_13.html' title='第五章 标准类型(3-1)'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11202605830313623292'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28827285.post-115278389363895515</id><published>2006-07-13T18:44:00.000+09:00</published><updated>2006-07-13T18:44:59.466+09:00</updated><title type='text'>第四章 容器，块和迭代器(2-2)</title><content type='html'>&lt;p class="MsoNormal" align="center"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;第四章  容器，块和迭代器(2-2)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UD"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;实现迭代器&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;迭代器就是一个简单的方法，它能调用代码块。第一眼看上去，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的块像&lt;/span&gt;&lt;span lang="EN-US"&gt;C&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;Java&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;Perl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的块一样，但这只是表面&lt;/span&gt;&lt;span lang="EN-US"&gt;--&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;实际上&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的块是分组语句的一种途径，而不是习惯上的那种。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;首先，块在源代码中紧挨着方法调用；并且和这个方法的最后一个参数&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或者带圆括号的参数&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;写在同一行上。其次，这个块内的代码不会在解释器遇到时立即被执行，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;首先会记住这个块出现的上下文环境（局部变量，当前对象等），然后进入方法。魔术就从这儿开始了。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在方法里面，这个块才会被&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语句调用执行，就像这个块是方法本身一样。无论何时&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;在方法中被执行，这个块就会被调用。当这个块执行完退出后，控制立即移交给&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;后面的语句（&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来自一个有&lt;/span&gt;&lt;span lang="EN-US"&gt;20&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;多年历史的语言：&lt;/span&gt;&lt;span lang="EN-US"&gt;CLU&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）。我们来看一个小例子。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def three_times&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;yield&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;yield&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;yield&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;three_times { puts "Hello" }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Hello&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Hello&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Hello&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这个块（两个大括号中的代码）被与调用它的方法&lt;/span&gt;&lt;span lang="EN-US"&gt;three_times&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;关联起来。在这个方法里面，&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;执行了&lt;/span&gt;&lt;span lang="EN-US"&gt;3&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;次，每次执行它都会调用块内的代码，即打印一个欢迎语句。然而是，什么会使块变得更有趣。是你可以给块传递参数，并且从块中得到结果。下面例子，我们将会得到小于一个指定值得&lt;/span&gt;&lt;span lang="EN-US"&gt;Fibonacci &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;数列。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def fib_up_to(max)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;i1, i2 = 1, 1 &lt;span style=""&gt;&lt;/span&gt;# parallel assignment (i1 = 1 and i2 = 1)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;while i1 &lt;= max&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;yield i1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;i1, i2 = i2, i1+i2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;fib_up_to(1000) {|f| print f, " " }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在这个例子中，&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语句有个参数。这个参数的值被传递给关联的块。在块的定义内，参数列表出现在两个竖线之间。在这个例子中变量&lt;/span&gt;&lt;span lang="EN-US"&gt;f&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;用来接收传递给&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的值，所以，这个块才能连续打印这个序列的成员。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;例子也显示了并列赋值行为，我们会在&lt;/span&gt;&lt;span lang="EN-US"&gt;85&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页讲到它。&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;尽管通常都传递一个值给块，但这不是必须的；块可以有任意数量的参数。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果传递给块的参数是现存的局部变量，这些局部变量将被用做块参数，而且它们的值可由于块的执行而被修改。这对于块内的变量也是一样的。如果它们第一次出现在块内，它们会被本地锁定。不同的是，如果它们第一次出现在块外，这些变量将在两个块之间及它们的环境内被共享。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;尽管有时很有用，这个特性还会产生意外行为，这在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;团体中产生激烈的争辩。在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby2.0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中将会修改块继承局部变量的方式。&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;做为试验的例子，我们看见块从当前范围内继承了变量&lt;/span&gt;&lt;span lang="EN-US"&gt;a&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;b&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，但传递给块的&lt;/span&gt;&lt;span lang="EN-US"&gt;c&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是本地的&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法&lt;/span&gt;&lt;span lang="EN-US"&gt;defined?&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;返回&lt;/span&gt;&lt;span lang="EN-US"&gt;nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，如果它的参数没有被定义的话&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = [1, 2]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b = 'cat'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a.each {|b| c = b * a[1] }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a &lt;span style=""&gt;&lt;/span&gt;! [1, 2]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b &lt;span style=""&gt;&lt;/span&gt;! 2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;defined?(c)&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;块也可以返回一个值给调用它的方法。这个块中的最后一个表达式的值将会做为&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的值被回传给方法。&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;&lt;span lang="EN-US"&gt;find&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法就是这样工作的。（&lt;/span&gt;&lt;span lang="EN-US"&gt;find&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法实际被定义在模块&lt;/span&gt;&lt;span lang="EN-US"&gt;Enumerable&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，它被混合插入到了类&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中。）&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Array&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def find&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;for i in 0...size&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 57.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;value = self[i]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 57.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;return value if yield(value)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;return nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;[1, 3, 5, 7, 9].find {|v| v*v &gt; 30 } &lt;span style=""&gt;&lt;/span&gt;! 7&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这个用法中数组将连续的元素传递给相关联的块。如果这个块返回&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，则这个方法返回当前对应的元素。如果没有匹配的元素，方法返回&lt;/span&gt;&lt;span lang="EN-US"&gt;nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。这个方法显示了迭代器的好处。&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类只作自己做拿手的事，访问数组元素，而分离的应用代码只关注它的特殊需求。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;一些迭代器对&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;集合中的很多类型是通用的。我们已经研究了&lt;/span&gt;&lt;span lang="EN-US"&gt;find&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。另外两个是&lt;/span&gt;&lt;span lang="EN-US"&gt;each&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;collect&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span lang="EN-US"&gt;each&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或许是最简单的迭代器&lt;/span&gt;&lt;span lang="EN-US"&gt;--&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;它们都会对集合的每个元素来调用块。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;[ 1, 3, 5,7,9 ].each { |i| puts i }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces: &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;7&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;9&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;&lt;span lang="EN-US"&gt;each&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;迭代器有特殊地位；第&lt;/span&gt;&lt;span lang="EN-US"&gt;97&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页我们将讨论它如何被用于基本的&lt;/span&gt;&lt;span lang="EN-US"&gt;for&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;loop&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，在&lt;/span&gt;&lt;span lang="EN-US"&gt;113&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页我们将看到如何定义&lt;/span&gt;&lt;span lang="EN-US"&gt;each&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，以便为你的类自由地添加更多的功能。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;另一个通用的迭代器是&lt;/span&gt;&lt;span lang="EN-US"&gt;collect&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，它从集合中获取每个元素并将它传递给块。由块处理后返回的结果被构建成一个新的数组。例如：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;["H", "A", "L"].collect {|x| x.succ } &lt;span style=""&gt;&lt;/span&gt;! ["I", "B", "M"]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;迭代器不仅仅只限于访问现存的数组和哈希表等集合结构上，就像我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;Fibonacci&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;例子中看到的，迭代器能返回被导出的值，这个能力被&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;用在了&lt;/span&gt;&lt;span lang="EN-US"&gt;input/output&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类中，它实现了一个迭代器接口，用它来返回&lt;/span&gt;&lt;span lang="EN-US"&gt;I/O&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;流内的连续行&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或字节&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;这个例子使用&lt;/span&gt;&lt;span lang="EN-US"&gt;do…end&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来定义块。这个定义与使用花括号来定义是一样的：&lt;/span&gt;&lt;span lang="EN-US"&gt;do…end&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的优先级低于&lt;/span&gt;&lt;span lang="EN-US"&gt;{…}&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;341&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页讨论这个区别的影响。&lt;/span&gt;&lt;span lang="EN-US"&gt;) &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;f = File.open("testfile")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;f.each do |line|&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts line&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;f.close&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;This is line one&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;This is line two&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;This is line three&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;And so on...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;让我们来看一个更有用的迭代器。&lt;/span&gt;&lt;span lang="EN-US"&gt;1.8&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;&lt;span lang="EN-US"&gt;inject(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;名字有些不直观，它定义在模块&lt;/span&gt;&lt;span lang="EN-US"&gt;Enumerable&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，它可让你遍历集合中的成员来累积值。例如，你可以为一个数组内的所有元素求和，并使用代码找到它们的结果。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;本书第一版中有作者模拟&lt;/span&gt;&lt;span lang="EN-US"&gt;inject&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的例子。&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;[1,3,5,7].inject(0) {|sum, element| sum+element} ! 16&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;[1,3,5,7].inject(1) {|product, element| product*element} ! 105&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;inject &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;这样工作：当被关联的块第一次被调用时，&lt;/span&gt;&lt;span lang="EN-US"&gt;sum&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;被设置为&lt;/span&gt;&lt;span lang="EN-US"&gt;inject&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的参数（本例为&lt;/span&gt;&lt;span lang="EN-US"&gt;0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;），&lt;/span&gt;&lt;span lang="EN-US"&gt;element&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;被设为集合内的第一个元素。第二次及以后块被调用时，&lt;/span&gt;&lt;span lang="EN-US"&gt;sum&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的值被设置为上次调用时由块返回的值。&lt;/span&gt;&lt;span lang="EN-US"&gt;inject&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的最终值是最后调用时块返回的值。&lt;/span&gt; &lt;span style="font-family: 宋体;"&gt;最后的可能是：如果&lt;/span&gt;&lt;span lang="EN-US"&gt;inject&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;被无参数调用，它使用集合的第一个元素做为它初值，并用第二个值开始迭代。这意味着我们可以重写上面的例子&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;[1,3,5,7].inject {|sum, element| sum+element} ! 16&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;[1,3,5,7].inject {|product, element| product*element} ! 105&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;内置的与外置的迭代器&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这值得我们再花些时间来比较&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;与其它语言如&lt;/span&gt;&lt;span lang="EN-US"&gt;C++&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;Java&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的迭代器。在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，迭代器是内置集合中的&lt;/span&gt;&lt;span lang="EN-US"&gt;—&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;它是个简单的方法，与其它的方法是同样，无论何时调用&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;它都产生一个新值。这样使用迭代器就好像是与这个方法相关联的块代码。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在其它语言中，集合不含有它们自己的迭代器，相反，它们生成额外的帮助对象&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;例如，&lt;/span&gt;&lt;span lang="EN-US"&gt;Java&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的&lt;/span&gt;&lt;span lang="EN-US"&gt;Iterator&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;接口&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，以携带迭代器状态。从这一方面，及其它很多方面来说，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是一种一目了然的语言。当你写&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;程序时，你关注于功能的实现，而不是构建脚手架来支持语言本身。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;或许应花些时间来看看&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的内置迭代器为什么有时不能更好地解决问题。一方面当你需要将迭代器视为一个对象的地方，它的表现就很不好。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;例如，传递迭代器到需要访问由那个迭代器返回的每个值的方法内&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。另外，在两个并行的集合上使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的内置迭代器重复也很困难。幸运地，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby1.8&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;带来了&lt;/span&gt;&lt;span lang="EN-US"&gt;Generator&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;库&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;662&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页描述&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，它提供了&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;在这种场合下使用的外置迭代器。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UF"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;用于事务处理中的块&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;虽然块通常用于迭代器，但它们也有其它用途。让我们看一些。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;你 可以使用块来定义一大块代码，这些代码必须在一定的事务控制下运行。比如，你经常会打开一个文件，对文件的内容作一些处理，然后当工作完成时，要确保文件 在最后会被关闭。尽管我们可以用常规代码实现，可有种观点认为文件应该自己负责关闭它自己。我们可用块来做到。一个简单例子如下（忽略了错误处理等）：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class File&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def File.open_and_process(*args)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;f = File.open(*args)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;yield f&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;f.close()&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;File.open_and_process("testfile", "r") do |file|&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;while line = file.gets&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 68.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;puts line&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;This is line one&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;This is line two&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;This is line three&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;And so on...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;open_and_process&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是一个类方法&lt;/span&gt;&lt;span lang="EN-US"&gt;—&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;它可以不依赖任何特定的&lt;/span&gt;&lt;span lang="EN-US"&gt;File&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象而被调用。我们希望它接受与常规的&lt;/span&gt;&lt;span lang="EN-US"&gt;File.open&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法一样的参数，但我们不关心这些参数是什么。要做到这些，我们可指定参数为&lt;/span&gt;&lt;span lang="EN-US"&gt;*args&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，意思是&lt;/span&gt;&lt;span lang="EN-US"&gt;”&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;收集传递给方法的参数到一名为&lt;/span&gt;&lt;span lang="EN-US"&gt;args&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的数组内&lt;/span&gt;&lt;span lang="EN-US"&gt;”&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。然后，我们可调用&lt;/span&gt;&lt;span lang="EN-US"&gt;File.open&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，并传递&lt;/span&gt;&lt;span lang="EN-US"&gt;*args&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;给它做为它的参数。它会展开数组以获取每个参数。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;一旦这个文件被打开，&lt;/span&gt;&lt;span lang="EN-US"&gt;open_and_process &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;将调用&lt;/span&gt;&lt;span lang="EN-US"&gt;yield&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，然后将打开的文件对象传递给这个块。当块返回后，这个文件将被关闭。这种情况下，关闭文件的任务就从使用文件对象的用户转变为文件本身了。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;让文件管理它们自己生命周期的技术是非常有用的，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;直接地支持&lt;/span&gt;&lt;span lang="EN-US"&gt;File&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类有这种功能。如果&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.ruby-cn.org/book/ProgrammingRuby/ref_c_file.html#File.open"&gt;&lt;span style="text-decoration: none;"&gt;File.open&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;有关联的块，那么这个块就会用传递过来文件对象作为参数被调用，然后，当块结束后，这个文件会被关闭。这很有趣，也就是说&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.ruby-cn.org/book/ProgrammingRuby/ref_c_file.html#File.open"&gt;&lt;span style="text-decoration: none;"&gt;File.open&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法有两种不同的行为：当带块调用时，它执行块然后关闭文件。当无块调用时，它返回这个文件的&lt;/span&gt;&lt;span lang="EN-US"&gt;file&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象。方法&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.ruby-cn.org/book/ProgrammingRuby/ref_m_kernel.html#Kernel.block_given_qm"&gt;&lt;span style="text-decoration: none;"&gt;Kernel::block_given?&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;提供了实现这种功能的可能，如果一个块被关联到当前方法，它返回&lt;/span&gt;&lt;span lang="EN-US"&gt;true&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。使用这个方法，你可以实现与&lt;/span&gt;&lt;span lang="EN-US"&gt;File.open&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;相似的自己的&lt;/span&gt;&lt;span lang="EN-US"&gt;open&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;再一次忽略错误处理&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class File&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def File.my_open(*args)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;result = file = File.new(*args)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# If there's a block, pass in the file and close&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# the file when it returns&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;if block_given?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;result = yield file&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;file.close&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;return result&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;前面的例子使用块来控制资源，我们没有地址错误的处理。如果我们想适当地实现这些方法，我们需要确保不论什么原因中止了代码的处理，文件都会被关闭。我们可以使用异常处理来做，我们稍后在&lt;/span&gt;&lt;span lang="EN-US"&gt;101&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页讨论它。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UG"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;块可以是闭包&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;让我们再回来看看自动点唱机。某些时候，我们需要用代码来管理用户界面&lt;/span&gt;&lt;span lang="EN-US"&gt;—&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;人们可以按下按钮选择歌曲并控制自动点唱机。我们需要给这些按钮指定相应的行为：按下&lt;/span&gt;&lt;span lang="EN-US"&gt;START&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;音乐开始。而&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的块就很适合干这样的事情。假设点唱机的设计者通过&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;扩展为我们提供了一个基本的按钮类。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;261&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页我们会谈到扩展&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;start_button = Button.new("Start")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;pause_button = Button.new("Pause")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# ...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;当用户按下按钮之后会发生什么呢？在&lt;/span&gt;&lt;span lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类内，硬件操纵以便调用方法，&lt;/span&gt;&lt;span lang="EN-US"&gt;button_pressed&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，将被调用。添加给这些按钮的功能很明显，就是创建&lt;/span&gt;&lt;span lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的子类，然后在每个子类中实现&lt;/span&gt;&lt;span lang="EN-US"&gt;button_pressed &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class StartButton &lt;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def initialize&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;super("Start") # &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;调用&lt;/span&gt;&lt;span lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类的&lt;/span&gt;&lt;span lang="EN-US"&gt;initialize&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def button_pressed&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;# do start actions...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;start_button = StartButton.new&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这样做有两个问题，首先，这样将导致产生大量子类。如果接口&lt;/span&gt;&lt;span lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变化了，所有子类都需要维护；第二，按钮按下之后需要执行的行为不应该在按钮上表示，它们不是按钮的特征而是使用这些按钮的点唱机的责任。我们可以用块来消除这二个问题。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;songlist = SongList.new&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class JukeboxButton &lt;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def initialize(label, &amp;action)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;super(label)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@action = action&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def button_pressed&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 63pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@action.call(self)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;start_button = JukeboxButton.new("Start") { songlist.start }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;pause_button = JukeboxButton.new("Pause") { songlist.pause }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;上面代码的关键点在&lt;/span&gt;&lt;span lang="EN-US"&gt;JukeboxButton#initialize&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的第二个参数。如果方法定义的最后一个参数是以&lt;/span&gt;&lt;span lang="EN-US"&gt;&amp;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;符号做前缀的话，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;会在那个方法被调用时查寻代码。如果代码块转向到类&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的一个对象而且被赋值为参数。那么你可以被这个参数视为任何其它变量。在本例中我们把它赋给实例变量&lt;/span&gt;&lt;span lang="EN-US"&gt;@action &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。当回调方法&lt;/span&gt;&lt;span lang="EN-US"&gt;button_pressed &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;被调用时，我们在那个对象上使用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.ruby-cn.org/book/ProgrammingRuby/ref_c_proc.html#Proc.call"&gt;Proc#call&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法来调用这个块。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;当创建一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象之后我们得到的是什么呢？很有趣，我们得到的不仅是一串代码，和这个块&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;定义相关联的上下文环境（范围内的）：&lt;/span&gt;&lt;span lang="EN-US"&gt;self&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;值，定义它的方法，变量，常量等。&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中的一个有趣的地方就是即使&lt;/span&gt;&lt;span lang="EN-US"&gt;block&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;定义时候的变量已经不在它的使用范围内，这个变量还保留着，仍可以使用。在其它语言中，这个特点被称为闭包。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;我们来看一个例子，这个例子使用方法&lt;/span&gt;&lt;span lang="EN-US"&gt;lambda&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，它把一个块转成一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def n_times(thing)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;return lambda {|n| thing * n }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;p1 = n_times(23)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;p1.call(3) ! 69&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;p1.call(4) ! 92&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;p2 = n_times("Hello ")&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;p2.call(3) ! "Hello Hello Hello "&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;方法&lt;/span&gt;&lt;span lang="EN-US"&gt;n_times &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;返回一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Proc&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象，这个对象引用了这个函数的参数：&lt;/span&gt;&lt;span lang="EN-US"&gt;thing &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。即使这个参数在块被调用时已经不在自己的作用域里了，这个块还是可以访问这个参数。（比如&lt;/span&gt;&lt;span lang="EN-US"&gt;p1.call(4)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，这个时候，虽然对&lt;/span&gt;&lt;span lang="EN-US"&gt;p1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的赋值语句中的参数&lt;/span&gt;&lt;span lang="EN-US"&gt;23&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;已经超出了作用域范围，但是它仍然保存着&lt;/span&gt;&lt;span lang="EN-US"&gt;23×4&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;＝&lt;/span&gt;&lt;span lang="EN-US"&gt;92&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。）&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;无所不在的容器&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;容器，块，和迭代器是&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的核心概念。&lt;/span&gt;&lt;span lang="EN-US"&gt; The more you write in Ruby, the more you’ll find yourself moving away from conventional looping constructs. Instead, you’ll write classes that support iteration over their contents. And you’ll find that this code is compact, easy to read, and a joy to maintain.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28827285-115278389363895515?l=nucleusg.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/115278389363895515/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=28827285&amp;postID=115278389363895515' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278389363895515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278389363895515'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/2006/07/2-2.html' title='第四章 容器，块和迭代器(2-2)'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11202605830313623292'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28827285.post-115278375342472904</id><published>2006-07-13T18:41:00.000+09:00</published><updated>2006-07-13T18:42:33.543+09:00</updated><title type='text'>第四章 容器，块和迭代器(2-1)</title><content type='html'>&lt;p class="MsoNormal" align="center"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;第四章  容器，块和迭代器(2-1)&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;    一个自动点唱机只有一首歌恐怕不会太流行，所以我们需要建立一个歌曲目录和一个等待播放的列表。这都是容器的例子，一个包含若干个对其它对象引用的对象。&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;    目录和播放列表都有类似的操作，增加歌曲，删除歌曲，返回歌曲列表等等。播放列表可能还需要别的方法，比如插入广告，记录累计播放时间等，我们将在后面考虑这些问题。现在，我们需要建立一个通用&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;SongList&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类，以便在目录和播放列表中使用。&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S1"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;容器&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt; text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在开始实现之前，我们要知道怎么在&lt;/span&gt;&lt;span lang="EN-US"&gt;SongList&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象中存储歌曲列表。我们有三个明显得选择：&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的提供的&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;提供的&lt;/span&gt;&lt;span lang="EN-US"&gt;Hash&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，或者我们自己创建一个列表结构。下面我们来看看数组合和哈希，然后选择一个来在我们的类中使用。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 24pt; text-align: left;" align="left"&gt;&lt;span style="font-size: 12pt; font-family: Times-Roman;" lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UA"&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;数组&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;类&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;持有一个对象引用的集合。每个对象引用占据数组的一个位置，用一个正整数索引标识。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;你可以使用字面值或者直接地创建一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象。字面值数组是一个简单的在两个方括号之间的对象列表，列表中的每个元素之间用逗号隔开。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;a = [ 3.14159, "pie", 99 ]&lt;span style=""&gt; &lt;/span&gt;#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;使用字面值数组。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a.class &lt;span style=""&gt;&lt;/span&gt;! Array&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a.length&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! 3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[0]&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! 3.14159&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[1]&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! "pie"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[2]&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! 99&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[3]&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;b = Array.new&lt;span style=""&gt; &lt;/span&gt;#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;直接创建&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b.class &lt;span style=""&gt;&lt;/span&gt;! Array&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b.length &lt;span style=""&gt;&lt;/span&gt;! 0&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b[0] = "second"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b[1] = "array"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;b &lt;span style=""&gt;&lt;/span&gt;! ["second", "array"]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;数组用&lt;/span&gt;&lt;span lang="EN-US"&gt;[ ]&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作符指定索引的下标，就像&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内的大多数操作符一样，它实际上也是一个方法&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;类&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的一个实例方法&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，因此它可以在子类中被覆写。就像例子中显示的，数组索引从&lt;/span&gt;&lt;span lang="EN-US"&gt;0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;开始。用正整数索引的数组，它返回在这个位置上的对象，或者当这个位置上没有任何对象时返回&lt;/span&gt;&lt;span lang="EN-US"&gt;nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。用负整数索引的数组，它的计算从尾部开始。（这时候最右边的索引下标为&lt;/span&gt;&lt;span lang="EN-US"&gt;-1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，不是&lt;/span&gt;&lt;span lang="EN-US"&gt;0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。想想也是，数学上那有&lt;/span&gt;&lt;span lang="EN-US"&gt;-0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;存在）。&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 12pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;　&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = [ 1, 3, 5, 7, 9 ]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[1]&lt;span style=""&gt; &lt;/span&gt;! 9&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[2]&lt;span style=""&gt; &lt;/span&gt;! 7&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[99]&lt;span style=""&gt; &lt;/span&gt;! nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;有关索引的配置在下页的图&lt;/span&gt;&lt;span lang="EN-US"&gt;4.1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中有更多的细节。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;shapetype id="_x0000_t75" coordsize="21600,21600" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"&gt;&lt;stroke joinstyle="miter"&gt;&lt;formulas&gt;&lt;f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;f eqn="sum @0 1 0"&gt;&lt;f eqn="sum 0 0 @1"&gt;&lt;f eqn="prod @2 1 2"&gt;&lt;f eqn="prod @3 21600 pixelWidth"&gt;&lt;f eqn="prod @3 21600 pixelHeight"&gt;&lt;f eqn="sum @0 0 1"&gt;&lt;f eqn="prod @6 1 2"&gt;&lt;f eqn="prod @7 21600 pixelWidth"&gt;&lt;f eqn="sum @8 21600 0"&gt;&lt;f eqn="prod @7 21600 pixelHeight"&gt;&lt;f eqn="sum @10 21600 0"&gt;&lt;/f&gt;&lt;path gradientshapeok="t"&gt;&lt;lock aspectratio="t"&gt;&lt;/lock&gt;&lt;shape id="_x0000_i1025" style="" type="#_x0000_t75"&gt;&lt;imagedata src="http:///C:DOCUME%7E1ADMINI%7E1LOCALS%7E1Tempmsohtml11clip_image001.emz"&gt;&lt;/imagedata&gt;&lt;/shape&gt;&lt;/path&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/formulas&gt;&lt;/stroke&gt;&lt;/shapetype&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;你也可以用一对数字&lt;/span&gt;&lt;span lang="EN-US"&gt;[start, count]&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;来对数组进行索引。这将返回一个新数组，它包含原数组中从&lt;/span&gt;&lt;span lang="EN-US"&gt;start&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;开始的&lt;/span&gt;&lt;span lang="EN-US"&gt;count&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个对象的引用。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = [ 1, 3, 5, 7, 9 ]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[1, 3] &lt;span style=""&gt;&lt;/span&gt;! [3, 5, 7]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[3, 1]&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! [7]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[3, 2]&lt;span style=""&gt; &lt;/span&gt;! [5, 7]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size: 12pt; font-family: 宋体;"&gt;　&lt;/span&gt;&lt;span style="" lang="EN-US"&gt; &lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;最后，你也可使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Range&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象或&lt;/span&gt;&lt;span lang="EN-US"&gt;Range&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;字面值来对数组进行索引，它的起止位置由两个或三个小点分隔。两个小点则包含&lt;/span&gt;&lt;span lang="EN-US"&gt;end&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;位置，而三个小点则不包含&lt;/span&gt;&lt;span lang="EN-US"&gt;end&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;位置。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = [ 1, 3, 5, 7, 9 ]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[1..3] &lt;span style=""&gt;&lt;/span&gt;! [3, 5, 7]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[1...3] &lt;span style=""&gt;&lt;/span&gt;! [3, 5]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[3..3] &lt;span style=""&gt;&lt;/span&gt;! [7]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[3..1]&lt;span style=""&gt; &lt;/span&gt;! [5, 7, 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;[ ]&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作符有个对应的&lt;/span&gt;&lt;span lang="EN-US"&gt;[ ]=&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作符，它可以让你设置数组内的元素。如果使用单整数索引，则这个位置上的元素被赋值符号右边的值替换。而中间没有涉及到的位置为设为&lt;/span&gt;&lt;span lang="EN-US"&gt;nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。如下面例子数组最大下标为&lt;/span&gt;&lt;span lang="EN-US"&gt;4&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，而对&lt;/span&gt;&lt;span lang="EN-US"&gt;a[6]&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;设置新值，&lt;/span&gt;&lt;span lang="EN-US"&gt;a[5]&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;则被设为&lt;/span&gt;&lt;span lang="EN-US"&gt;nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = [ 1, 3, 5, 7, 9 ]&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! [1, 3, 5, 7, 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[1] = ’bat’ &lt;span style=""&gt;&lt;/span&gt;! [1, "bat", 5, 7, 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[3] = ’cat’ &lt;span style=""&gt;&lt;/span&gt;! [1, "bat", "cat", 7, 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[3] = [ 9, 8 ] &lt;span style=""&gt;&lt;/span&gt;! [1, "bat", "cat", [9, 8], 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[6] = 99 &lt;span style=""&gt;&lt;/span&gt;! [1, "bat", "cat", [9, 8], 9, nil, 99]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果在&lt;/span&gt;&lt;span lang="EN-US"&gt;[ ]=&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;操作符中下标索引为两个数字（一个开始位置，一个长度）或者一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Range&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;字面值，则原始数组内对应的一系列值将被替换为操作符右边的值。如果第二个参数即长度为&lt;/span&gt;&lt;span lang="EN-US"&gt;0&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，则右边的值将被插入到数组当前位置的前面；而且不会有值被删除。如果操作符的右边它本身就是个数组，则使用它的元素进行替换。如果&lt;/span&gt;&lt;span lang="EN-US"&gt;[ ]=&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;右边的长度和左边下标中指定的长度不一样，则原数组会自动进行调整。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a = [ 1, 3, 5, 7, 9 ]&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! [1, 3, 5, 7, 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[2, 2] = ’cat’&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! [1, 3, "cat", 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[2, 0] = ’dog’ &lt;span style=""&gt;&lt;/span&gt;! [1, 3, "dog", "cat", 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[1, 1] = [ 9, 8, 7 ]&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! [1, 9, 8, 7, "dog", "cat", 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[0..3] = [] &lt;span style=""&gt;&lt;/span&gt;! ["dog", "cat", 9]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;a[5..6] = 99, 98&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! ["dog", "cat", 9, nil, nil, 99, 98]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;数组有很多有用的方法，使用这些方法你能用数组实现队列，堆栈，列表等各种数据结构。&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法的完整介绍在第&lt;/span&gt;&lt;span lang="EN-US"&gt;406&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页。&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UB"&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;哈希表&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;哈希表&lt;/span&gt;&lt;span lang="EN-US"&gt; (&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;关联数组，映射或字典&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;与数组类似，它们都是以索引操作对象引用的集合。但是，你只能用整数索引数组，但你却可以用任何类型的对象来索引哈希表：字符串，正则表达式，等等。当你在哈希表内存储值时，你实际上应提供二个对象&lt;/span&gt;&lt;span lang="EN-US"&gt;–-&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;索引，通常称为&lt;/span&gt;&lt;span lang="EN-US"&gt;key&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，和一个值&lt;/span&gt;&lt;span lang="EN-US"&gt;value&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。你可以在随后用同样&lt;/span&gt;&lt;span lang="EN-US"&gt;key&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span lang="EN-US"&gt;hash&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;值索引来取回这个值。哈希表内的值可以是任何类型的对象。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;下面的例子使用了哈希表字面值：在两个花括号之间的&lt;/span&gt;&lt;span lang="EN-US"&gt;key=&gt;value&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;列表。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;h = { 'dog' =&gt; 'canine', 'cat' =&gt; 'feline', 'donkey' =&gt; 'asinine' }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;h.length&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! 3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;h['dog']&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! "canine"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;h['cow'] = 'bovine'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;h[12] = 'dodecine'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;h['cat'] = 99&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;h&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! {"cow"=&gt;"bovine", "cat"=&gt;99, 12=&gt;"dodecine",&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 68.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;"donkey"=&gt;"asinine", "dog"=&gt;"canine"}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;与数组相比，哈希表有个很大的优势：它们可以使用任何对象作为索引。但是，哈希表也有明显的缺点：它们的元素不能被排序，所以你不能轻易地用&lt;/span&gt;&lt;span lang="EN-US"&gt;hash&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;表来实现堆栈或队列。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内你会找到使用哈希表的更通用的数据结构。由类&lt;/span&gt;&lt;span lang="EN-US"&gt;Hash&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;实现的方法清单在第&lt;/span&gt;&lt;span lang="EN-US"&gt;471&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页中给出。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UC"&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;实现一个&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt;" lang="EN-US"&gt;SongList &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt; font-family: 宋体;"&gt;容器&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 12pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;现在，我们要准备实现自动点唱机的&lt;/span&gt;&lt;span lang="EN-US"&gt;SongList&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。首先我们创建一个&lt;/span&gt;&lt;span lang="EN-US"&gt;SongList&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内需要的基本方法列表。我们将更多地增加它功能，但现在还不行。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;append(song) &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;→&lt;/span&gt;&lt;span lang="EN-US"&gt; list&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;添加给定歌曲到列表内。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;delete_first() &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;→&lt;/span&gt;&lt;span lang="EN-US"&gt;song&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;从列表的前面移除第一首歌，并返回它。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;delete_last() &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;→&lt;/span&gt;&lt;span lang="EN-US"&gt; song&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;从列表的尾部移除一首歌，并返回它。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;[index] &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;→&lt;/span&gt;&lt;span lang="EN-US"&gt; song&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;返回由整数索引指定歌。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;with_title(title) &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;→&lt;/span&gt;&lt;span lang="EN-US"&gt;song&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;返回与给定标题相应的歌曲&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;上面清单给了我们如何实现的提示。能添加歌曲到尾部，能从前后两端移除，这暗示我们可以使用一个双向队列，当然，我们知道可以使用数组来实现它。同样地，可以从数组支持的列表中以整数位置值返回一首歌。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;但是，也需要能通过歌名来取出一首歌，这暗示我们应该使用哈希表，用标题作&lt;/span&gt;&lt;span lang="EN-US"&gt;key&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;用歌曲做&lt;/span&gt;&lt;span lang="EN-US"&gt;value&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。可是我们应该使用哈希表吗？当然，但这有些问题。首先，哈希表不能排序，所以我们大楖需要使用一个辅助的数组来保持列表的次序。其次，最大的问题是哈希表不支持带有同样&lt;/span&gt;&lt;span lang="EN-US"&gt;value&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的多个&lt;/span&gt;&lt;span lang="EN-US"&gt;key&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。对于我们的播放列表也是个问题，同一首歌可能被排在队列中多次。所以，我们现在将使用一个歌曲数组，当需要时用歌名查找它。如果这成为性能的瓶颈的话，我们总是可增加一些以哈希表为基础的查找。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;现在我们用基本的&lt;/span&gt;&lt;span lang="EN-US"&gt;initialize&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法开始我们的类，它创建我们用于存储歌曲的数组并在实例变量&lt;/span&gt;&lt;span lang="EN-US"&gt;@songs&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;存储对它的引用。&lt;/span&gt;&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class SongList&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def initialize&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@songs = Array.new&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;SongList#append&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法添加给定的歌曲到&lt;/span&gt;&lt;span lang="EN-US"&gt;@songs&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;数组的尾部。它也返回&lt;/span&gt;&lt;span lang="EN-US"&gt;self&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，是一个对当前&lt;/span&gt;&lt;span lang="EN-US"&gt;SongList&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象的引用。这个习惯很有用，它可以让我们链接多个对&lt;/span&gt;&lt;span lang="EN-US"&gt;append&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的调用。我们看看这个例子的最后版本。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class SongList&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def append(song)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@songs.push(song)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;self&lt;span style=""&gt; &lt;/span&gt;#&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;返回当有对象。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;然后，我们将增加&lt;/span&gt;&lt;span lang="EN-US"&gt;delete_first&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;delete_last&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，通常使用&lt;/span&gt;&lt;span lang="EN-US"&gt;Array#shift&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;Array#pop&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法来实现。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class SongList&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def delete_first&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@songs.shift&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def delete_last&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@songs.pop&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;到现在一切正常。我们的下一个方法是&lt;/span&gt;&lt;span lang="EN-US"&gt;[ ]&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，它通过索引访问元素。这些简单的委托方法频繁地出现在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;代码中：如果你的代码只包含有一，两行代码的方法，你可以更好的设计它，而不要麻烦使用委托方法。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class SongList&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def [](index)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@songs[index]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;现在，需要快速测试。要这么做，我们需要使用一个测试框架，叫&lt;/span&gt;&lt;span lang="EN-US"&gt;TestUnit&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中自带它。现在我不想完整地描述它&lt;/span&gt;&lt;span lang="EN-US"&gt;(143&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页的单元测试会祥细地描述它&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。现在，我们只需要&lt;/span&gt;&lt;span lang="EN-US"&gt;assert_equal&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，它检查两个参数是否相等，如果不相等它会给出信息。同样，&lt;/span&gt;&lt;span lang="EN-US"&gt;assert_nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法在它的以数为&lt;/span&gt;&lt;span lang="EN-US"&gt;nil&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时给出信息。我们使用这些断言来检查从列表中删除正确的歌曲。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;测试包括一些初始管理，必须通知&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;使用&lt;/span&gt;&lt;span lang="EN-US"&gt;TestUnit&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;框架，及告诉这个框架我们写了一些测试代码。然后，我们创建一个&lt;/span&gt;&lt;span lang="EN-US"&gt;SongList&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和四个&lt;/span&gt;&lt;span lang="EN-US"&gt;song&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象，并添加&lt;/span&gt;&lt;span lang="EN-US"&gt;song&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象到列表中。&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;我们使用&lt;/span&gt;&lt;span lang="EN-US"&gt;append&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;返回的&lt;/span&gt;&lt;span lang="EN-US"&gt;SongList&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象来将这些方法的调用链接起来。&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;然后，我们可测试&lt;/span&gt;&lt;span lang="EN-US"&gt;[ ]&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，检查它对一组索引能否返回正确的歌曲&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;nil)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。最后，我们从列表的&lt;/span&gt;&lt;span lang="EN-US"&gt;start&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;及&lt;/span&gt;&lt;span lang="EN-US"&gt;end&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;值中删除歌曲，并检查这些歌曲是否被返回。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;require 'test/unit'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class TestSongList &lt;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def test_delete&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;list = SongList.new&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;s1 = Song.new('title1', 'artist1', 1)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;s2 = Song.new('title2', 'artist2', 2)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;s3 = Song.new('title3', 'artist3', 3)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;s4 = Song.new('title4', 'artist4', 4)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;list.append(s1).append(s2).append(s3).append(s4)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;assert_equal(s1, list[0])&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;assert_equal(s3, list[2])&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;assert_nil(list[9])&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;assert_equal(s1, list.delete_first)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;assert_equal(s2, list.delete_first)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;assert_equal(s4, list.delete_last)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;assert_equal(s3, list.delete_last)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;assert_nil(list.delete_last)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Loaded suite Started&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Finished in 0.002314 seconds.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;1 tests, 8 assertions, 0 failures, 0 errors&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;运行测试确定，一个测试内的八个断言全部通过。我们的自动点唱机可以正常工作了。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;现在，我们需要添加一些功能，以使它可以通过标题查找歌曲。这包括对列表内歌曲进行扫描，以检查每个标题的歌曲。要做到这些，我们首先需要花费一些时间来讨论&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的嵌套特征：迭代器。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S2"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;块和迭代器&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt; text-align: left;" align="left"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;我们的下一个问题是，&lt;/span&gt;&lt;span lang="EN-US"&gt;SongList&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;要实现&lt;/span&gt;&lt;span lang="EN-US"&gt;with_title&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法来获取字符串并用标题来搜索歌曲。实现起来似乎很容易：我们已有一个歌曲数组，所以每次都遍历它的每个元素，来查找一个匹配。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class SongList&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def with_title(title)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;for i in 0...@songs.length&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;return @songs[i] if title == @songs[i].name&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;return nil&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这样已经可以工作了，但看起来不是很爽：用一个&lt;/span&gt;&lt;span lang="EN-US"&gt;for&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;循环在数组上进行迭代。有没有更自然的写法呢？&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;以这种方式，我们的&lt;/span&gt;&lt;span lang="EN-US"&gt;for&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;循环与数组太亲密了；它请求了一个&lt;/span&gt;&lt;span lang="EN-US"&gt;length&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，然后它依次取回找到的匹配值。为什么不请求数组来对它的每个成员进行测试呢？在&lt;/span&gt;&lt;span lang="EN-US"&gt;Array&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中我们可找到这样的方法。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class SongList&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def with_title(title)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@songs.find {|song| title == song.name }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;方法&lt;/span&gt;&lt;span lang="EN-US"&gt;find&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;是一个迭代器&lt;/span&gt;&lt;span lang="EN-US"&gt;—&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;它重复地调用代码块。代码块与迭代器都是&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中比较有趣的特点。所以，让们花些时间来看看它们。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28827285-115278375342472904?l=nucleusg.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/115278375342472904/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=28827285&amp;postID=115278375342472904' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278375342472904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278375342472904'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/2006/07/2-1.html' title='第四章 容器，块和迭代器(2-1)'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11202605830313623292'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28827285.post-115278366365451104</id><published>2006-07-13T18:40:00.000+09:00</published><updated>2006-07-13T18:41:10.076+09:00</updated><title type='text'>第三章 类，对象和变量(3-3)</title><content type='html'>&lt;p class="MsoNormal" align="center"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;第三章 类，对象和变量(3-3)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S4"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;访问控制&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;我们设计一个类的接口的时候，一个重要的问题是，我们应该向外界暴露多少内部实现，外部能访问我们的类有多少限制。如果过多的让外部访问内部的东西，可能增加了耦合，用户越来越依赖我们的类的内部实现，而不是逻辑接口。好消息是在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内改变对象状态有个很容易的方式，就是调用它的方法。控制对方法的访问，你就能控制对对象的访问。一个好的小技巧是从不暴露能让你对象处于无效状态的方法。&lt;/span&gt; &lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;提供了三种保护层次：&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal" style="text-indent: -21pt;"&gt;&lt;span style="font-family: Wingdings;" lang="EN-US"&gt;&lt;span style=""&gt;l&lt;span style="font-weight: normal; font-size: 7pt; line-height: normal; font-style: normal; font-variant: normal;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: -21pt;"&gt;&lt;span style="font-family: Wingdings;" lang="EN-US"&gt;&lt;span style=""&gt;&lt;span style="font-size:100%;"&gt;l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Public methods &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;任何人都可以调用，没有强制的访问控制。方法默认都是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;（&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;initialize&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;除外）。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: -21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: Wingdings;" lang="EN-US"&gt;&lt;span style=""&gt;l&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Protected methods &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;可以在本类或者子类中调用。访问控制在家族内。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: -21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: Wingdings;" lang="EN-US"&gt;&lt;span style=""&gt;l&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Private methods &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;不能用显示的接收者来调用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;—&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;接收者总是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。这意味着私有方法仅能在当前对象的上下文环境中被调用；你不可以调用其它对象的私有方法。&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;"protected"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;"private"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;两者的区别非常微妙，在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，两者的关系和在其他语言中是不一样的。如果一个方法是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;protected&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的，它可以在定义它的实例或者子类的实例来调用。如果一个方法是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;"private"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的，只可以在这个方法所处的对象中被使用，不能直接调用另一个对象的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法。甚至这个对象就是调用者本身。&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br /&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;和其他&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;oo&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;语言另一个重要的不同点在于，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;动态确定访问控制，在程序运行而不是静止时，只有你运行到那一行，才会去判断是否出错。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UG"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;指定访问控制&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;你在类内部或模块定义时使用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;protected&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，与&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;三个中的一个或多个来指定方法的访问等级。每个控制都有两种使用方式。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果不带参数使用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; public/protected/private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，那么这后面的方法默认都是指定的值，比如一行写了&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，那么后面的方法默认都是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，除非指定了另外的访问控制符。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;class MyClass&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def method1 # default is 'public'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;#...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;protected # &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;后面方法将是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; 'protected'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def method2 # will be 'protected'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;#...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;private # &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;后面方法将是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; 'private'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def method3 # will be 'private'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;#...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;public # subsequent methods will be 'public'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def method4 # and this will be 'public'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;#...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;另一种方法，定义方法的时候不指定访问控制符，而是将相关的方法列在对应的访问控制后面，比如：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;class MyClass&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def method1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;# ... and so on&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;public :method1, :method4&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;protected :method2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;private :method3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;initialize&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法自动声明为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;型。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;现在来看看一个例子。假如我们有一个记帐系统，每一个借方（&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;debit&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）对应一个贷方（&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;credit&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;），我们要求都必须遵守这个规则，所以我们把&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;debit&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;credit&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的方法设成&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，提供了一个外部接口来处理：&lt;/span&gt;&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;class Accounts&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def initialize(checking, savings)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;@checking = checking&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;@savings = savings&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def debit(account, amount)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;account.balance =&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;amount&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def credit(account, amount)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;account.balance += amount&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;#...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def transfer_to_savings(amount)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;debit(@checking, amount)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;credit(@savings, amount)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;#...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S5"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;Protected&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;span style="font-family: 宋体;"&gt;访问控制被用于当对象需要访问同一类的其它对象的内部状态时。例如，我们可能想允许个别&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Account&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family: 宋体;"&gt;对象来比较它们账户，但是可能想隐藏这些账户的余额。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;class Account&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;attr_reader :balance &lt;span style=""&gt;&lt;/span&gt;# &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family: 宋体;"&gt;属性存取器方法&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;'balance'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;protected :balance &lt;span style=""&gt;&lt;/span&gt;# and make it protected&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;def greater_balance_than(other)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;return @balance &gt; other.balance&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;span style="font-family: 宋体;"&gt;因为&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;balance &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family: 宋体;"&gt;属性是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;protected&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family: 宋体;"&gt;，它只对&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Account&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family: 宋体;"&gt;对象内部有效。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;变量&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;Variables&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt;" lang="EN-US"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;现在，我们的麻烦是要创建所有些对象，确保我们不要丢下谁。变量用来跟踪一个对象的状态；每个变量持有一个指向对象的引用。&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;让我们确认一下这些代码。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person = "Tim"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person.id &lt;span style=""&gt;&lt;/span&gt;! 936870&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person.class &lt;span style=""&gt;&lt;/span&gt;! String&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person &lt;span style=""&gt;&lt;/span&gt;! "Tim"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;第一行，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;创建了一个带有值&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;”Tim”&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的新字符串对象，对这个对象的引用被放置在局部变量&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;person&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中。&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;快速测试显示，这个变量的确获得了字符串，带有一个&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;objectID,&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;一个类，及一个值。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;但变量是对象吗？&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，答案是否定的。一个变量只是指向一个对象的引用。这些对象可能正在某地，比如堆栈中，变量只是指向了这些对象。&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br /&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&lt;span style="font-size:130%;"&gt;我们再看看稍微负责的例子&lt;/span&gt;&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person1 = "Tim"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person2 = person1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person1[0] = 'J'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person1 ! "Jim"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person2 ! "Jim"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;发生了什么事？我们改变了&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;person1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的第一个字符，但是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;person1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;与&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;person2&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;两都都从&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;”Time”&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;变成了&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;”Jim”&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;这是因为变量只是指向一个对象的引用，而不是对象本身。赋值语句&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;person2 = person1 &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;没有创建新的对象，只是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;person2&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;拷贝了&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;person1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的引用而已。所以&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;person1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;person2&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;都指向了同一个对象。我们可以在下页的图&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;3.1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中看到这些。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;有时候赋值语句只是为对象建立了别名，而潜在的创建了新的变量指向同一个对象。但是这不会在我们的代码中引起问题吗？它能，但并不像你想的那么容易出错。例如，图&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;3.1&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内的例子，我们可以用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;dup&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;方法，这个方法会创建一个新的字符串对象，并且内容和消息接受者（方法执行者）一样。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person1 = "Tim"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person2 = person1.dup&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person1[0] = "J"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person1&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;! "Jim"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person2 &lt;span style=""&gt;&lt;/span&gt;! "Tim"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;如果你不想别人修改一个对象，也可以冻结（&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;freezing&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;）这个对象（我们在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;377&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;页谈论冻结对象）。如果你修改一个被冻结的对象，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;会抛出一个&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;TypeError&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;异常。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person1 = "Tim"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person2 = person1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person1.freeze # prevent modifications to the object&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;person2[0] = "J"&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 31.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;produces:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;prog.rb:4:in `[]=': can't modify frozen string (TypeError)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 42pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;font-size:130%;"&gt;from prog.rb:4&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;shapetype id="_x0000_t75" coordsize="21600,21600" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"&gt;&lt;stroke joinstyle="miter"&gt;&lt;formulas&gt;&lt;f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;f eqn="sum @0 1 0"&gt;&lt;f eqn="sum 0 0 @1"&gt;&lt;f eqn="prod @2 1 2"&gt;&lt;f eqn="prod @3 21600 pixelWidth"&gt;&lt;f eqn="prod @3 21600 pixelHeight"&gt;&lt;f eqn="sum @0 0 1"&gt;&lt;f eqn="prod @6 1 2"&gt;&lt;f eqn="prod @7 21600 pixelWidth"&gt;&lt;f eqn="sum @8 21600 0"&gt;&lt;f eqn="prod @7 21600 pixelHeight"&gt;&lt;f eqn="sum @10 21600 0"&gt;&lt;/f&gt;&lt;path gradientshapeok="t"&gt;&lt;lock aspectratio="t"&gt;&lt;/lock&gt;&lt;shape id="_x0000_i1025" style="" type="#_x0000_t75"&gt;&lt;imagedata src="http:///C:DOCUME%7E1ADMINI%7E1LOCALS%7E1Tempmsohtml11clip_image001.emz"&gt;&lt;/imagedata&gt;&lt;/shape&gt;&lt;/path&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/f&gt;&lt;/formulas&gt;&lt;/stroke&gt;&lt;/shapetype&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: 宋体;"&gt;对&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内的类与对象的总结。这些东西很重要；你在&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style="font-family:Times New Roman;"&gt;Ruby&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内操纵的每个东西都是对象。我们用对象做的最多的事情就是创建它们集合。但这是我们下章的主题。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28827285-115278366365451104?l=nucleusg.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nucleusg.blogspot.com/feeds/115278366365451104/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=28827285&amp;postID=115278366365451104' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278366365451104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/28827285/posts/default/115278366365451104'/><link rel='alternate' type='text/html' href='http://nucleusg.blogspot.com/2006/07/3-3.html' title='第三章 类，对象和变量(3-3)'/><author><name>+GENIO+</name><uri>http://www.blogger.com/profile/12406040310212741785</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11202605830313623292'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-28827285.post-115278354894916453</id><published>2006-07-13T18:38:00.000+09:00</published><updated>2006-07-13T18:39:41.296+09:00</updated><title type='text'>第三章 类，对象和变量(3-2)</title><content type='html'>&lt;p class="MsoNormal" align="center"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;第三章 类，对象和变量(3-2)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UB"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:15;"  &gt;&lt;span style="font-size:130%;"&gt;可写属性&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:15;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;有时候你需要在外部对对象的属性进行设置。比如，一首歌的时长这个属性可能开始的时候只是一个估算的值&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;或许是从&lt;/span&gt;&lt;span lang="EN-US"&gt;CD&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;或&lt;/span&gt;&lt;span lang="EN-US"&gt;MP3&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;上采集的信息&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。当第一次播放的时候，我们知道了它的真正时长，并且要把这个新值写回到&lt;/span&gt;&lt;span lang="EN-US"&gt;Song&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象中。&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;span lang="EN-US"&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;c++&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;或者&lt;/span&gt;&lt;span lang="EN-US"&gt;java&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中，我们可以用&lt;/span&gt;&lt;span lang="EN-US"&gt;setter&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;方法。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class JavaSong { // Java code&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;private Duration _duration;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;public void setDuration(Duration newDuration) {&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 52.5pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;_duration = newDuration;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;s = new Song(....);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;s.setDuration(length);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中，可以象其他变量一样访问一个对象的属性。我们已经看见了上面的短句如&lt;/span&gt;&lt;span lang="EN-US"&gt;song.name&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。所以当你想设置一个属性的值时，应该能很自然地给这些变量赋值。在&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中，你可以创建一个方法来做到这些，方法的名字用一个等于符号结尾。这些方法可以被用做赋值的目标。&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Song &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def duration=(newDuration) &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@duration = newDuration &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;aSong = Song.new("Bicylops", "Fleck", 260) &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;aSong.duration &lt;span style=""&gt;&lt;/span&gt;}} 260 &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;aSong.duration = 257 # set attribute with updated value &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;aSong.duration &lt;span style=""&gt;&lt;/span&gt;}} 257 &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;赋值语句&lt;/span&gt;&lt;span lang="EN-US"&gt;"aSong.duration = 257"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;调用了&lt;/span&gt;&lt;span lang="EN-US"&gt;song&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象中的方法&lt;/span&gt;&lt;span lang="EN-US"&gt;duration= &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，并将&lt;/span&gt;&lt;span lang="EN-US"&gt;257&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;做为参数传递给它。实际上，定义一个方法名以&lt;/span&gt;&lt;span lang="EN-US"&gt;=&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;符号结尾的方法，可以使这个属性出现左边的赋值语句一样。同样，&lt;/span&gt;&lt;span lang="EN-US"&gt;Ruby&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;也为创建属性设置方法提供了一个捷径。&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:宋体;font-size:12;"  lang="EN-US" &gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Song&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;attr_writer :duration&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;aSong = Song.new("Bicylops", "Fleck", 260)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;aSong.duration = 257&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UC"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;虚拟属性&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;这些属性存取方法不是对一个对象实例变量的简单包装。比如，你需要得到以分钟为单位的时长，而不是以秒为单位：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;class Song&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def duration_in_minutes&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@duration/60.0 # force floating point&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;def duration_in_minutes=(new_duration)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 47.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;@duration = (new_duration*60).to_i&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 36.75pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;song = Song.new("Bicylops", "Fleck", 260)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;song.duration_in_minutes ! 4.33333333333333&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;song.duration_in_minutes = 4.2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:130%;"&gt;song.duration ! 252&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;这里我们使用属性方法建立了一个虚拟的实例变量，对于外面来说&lt;/span&gt;&lt;span lang="EN-US"&gt;duration_in_minutes&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;可以看作和其他一样的属性。尽管在内部，它并没有相应的实例变量。&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;这并不止是有趣而已，在&lt;/span&gt;&lt;span lang="EN-US"&gt;Bertrand Meyer &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的杰作《&lt;/span&gt;&lt;span lang="EN-US"&gt;Object-Oriented Software Construction&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;》&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中，作者称这叫做统一访问原则（&lt;/span&gt;&lt;span lang="EN-US"&gt;Uniform Access Principle&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;）。通过隐藏实例变量与被计算出的值之间区别，你就可以不用在你的类实现里来处理这些问题，而且，当需要改动的时候，你只需要改动一个文件，而不是很多文件。&lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;这是最大的胜利。&lt;/span&gt;&lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 15.75pt;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="S3"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;属性，实例变量与方法&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;属性的描述可能对你更好地理解了方法没有太大帮助&lt;/span&gt;&lt;span lang="EN-US"&gt;--&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;为什么我们需要为它们调用一个想像的名字？在某种程序上，这是绝对正确的。属性就是方法。有时候属性只是简单地返回实例变量的值。有时候属性返回计算后的结果。有时候那么让人担心的，以&lt;/span&gt;&lt;span lang="EN-US"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;符号结尾的方法被用于更新对象的状态。那么问题是，属性在哪儿中止以及正常的方法从哪儿开始？一个属性能做那些旧方法不能做的事情？&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;当你设计类时，你决定它有什么内部状态，同样也决定状态如何在外部出现&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;给你的类用户&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;span style="font-family:宋体;"&gt;。内部状态持有实例变量。外部状态通过我们调用属性被展现出来。你的类可以完成其它行为只是正常的方法。这并不是它们之间的真正区别，但是，通过属性调用对象的外部状态，你可以帮助别人知道如何观察你写的类。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style=""&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;类变量和类方法&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt; text-align: left;" align="left"&gt;&lt;span style="font-family:宋体;"&gt;&lt;span style="font-size:130%;"&gt;到目前为止我们创建的所有类都包含实例变量和实例方法：变量与类的特定实例相关联，方法在这些变量上工作。有时候，类本身需要有它们自己的状态。这就引入了类变量。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="UD"&gt;&lt;b style=""&gt;&lt;span style=";font-family:宋体;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;类变量&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;b style=""&gt;&lt;span lang="EN-US"  style="font-size:14;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 26.25pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;类变量在类的所有对象之间共享，也可以被下面要提到的类方法修改。对于给定类，类变量只有一个拷贝存大。类变量名字以两个&lt;/span&gt;&lt;span lang="EN-US"&gt;”at”&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;符号&lt;/span&gt;&lt;span lang="EN-US"&gt;"@@"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;开头，比如&lt;/span&gt;&lt;span lang="EN-US"&gt;"@@count"&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。不像全局变量和实例变量，类变量在使用之前必须被初始化。通常在类定义体中由一条赋值语句初始化。&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 21pt;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:宋体;"&gt;比如，在我们的自动点唱机中，我们想记录每首歌被播放过多少次，这个次数或许是&lt;/span&gt;&lt;span lang="EN-US"&gt;Song&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对象的一个实例变量，当歌曲被被播放时，实例对象内的这个变量要加&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。如果我们还想计算所有歌曲