Ruby程序员修炼之道(第2版)

978-7-115-40503-6
作者: 【美】David A. Black(戴维 A. 布莱克)
译者: 钟凤鸣陈雪静
编辑: 杨海玲

图书目录:

详情

本书从Ruby编程语言的基础开始一直讲到动态特性,其中包含大量的真实代码示例并附有详细的注解,对日常使用Ruby进行编程中会遇到的每个知识点都进行了清晰的讲解。本书的内容由浅入深,主要包含Ruby编程语言的语法、面向对象的特性、默认对象self、控制流技术、常用的内置类、正则表达式、I/O操作,最后用大量的篇幅讲述了Ruby中最值得关注的动态特性。

图书摘要

版权信息

书名:Ruby程序员修炼之道(第2版)

ISBN:978-7-115-40503-6

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

• 著    [美] David A. Black

  译    钟凤鸣 陈雪静

  责任编辑 杨海玲

• 人民邮电出版社出版发行  北京市丰台区成寿寺路11号

  邮编 100164  电子邮件 315@ptpress.com.cn

  网址 http://www.ptpress.com.cn

• 读者服务热线:(010)81055410

  反盗版热线:(010)81055315


Original English language edition, entitled The Well-Grounded Rubyist, Second Edition by David A. Black published by Manning Publications Co., 209 Bruce Park Avenue, Greenwich, CT 06830. Copyright ©2014 by Manning Publications Co.

Simplified Chinese-language edition copyright ©2015 by Posts & Telecom Press. All rights reserved.

本书中文简体字版由Manning Publications Co.授权人民邮电出版社独家出版。未经出版者书面许可,不得以任何方式复制或抄袭本书内容。

版权所有,侵权必究。


这是一本深受好评的书。它不仅是一本纯Ruby的书,也不仅是一本纯Rails的书,而是一本为Rails程序员“优化”过的Ruby书。

本书从Ruby编程语言的基础开始一直讲到动态特性,其中包含大量的真实代码示例并附有详细的注解,对日常使用Ruby进行编程中会遇到的每个知识点都进行了清晰的讲解。本书的内容由浅入深,主要包含Ruby编程语言的语法、面向对象的特性、默认对象self、控制流技术、常用的内置类、正则表达式、I/O操作,最后用大量的篇幅讲述了Ruby中最值得关注的动态特性。

本书不仅适合Ruby编程语言的初学者,也适合有经验的开发者以及那些想要真正提升Ruby编程技术的爱好者阅读和学习,具有极高的参考价值。


“如果要学习Ruby语言,就从这本书开始吧!只用这一本足矣。”

——John Griffin, Overstock.com

“David Black对Ruby语言的理解以及他传授这门知识的能力都是非凡的。”

——Philip Hallstrom, PJKH, LLC

“经过漫长等待,继Ruby for Rails一书之后David的又一力作问世,这次是对Ruby学习的进一步深化。”

——Rick DeNatale, DenHaven Consulting

“想用Ruby学习面向对象或常规编程的所有人的必读之书。”

——Robert Klemme, Orga Systems

“David Black再次创作了一本属于每一位Ruby程序员的案头参考书。”

——Robert Dempsey, Atlantic Dominion Solutions

“如果想学Ruby语言,这是目前为止最好的一本书。”

——M. Edward (Ed) Borasky, ADP

“想知道Ruby的内部工作原理?David Black在本书中为你揭秘。”

——Patrick Steger, Zühlke Engineering AG

“一本翔实的、基于例子并有绝佳代码示例的Ruby编程语言教程,是学习这门语言绝好的书。”

——Doug Warren, Java Web Services

“我多么希望我当时学习Rails的时候就有这本书。”

——Patrick Dennis, Management Dynamics, Inc.

“继Ruby for Rails之后的又一力作。”

——Mark Eagle, Intercontinental Exchange, Inc.

“强烈推荐给每一位Ruby学习者。”

——Greg Donald, VUMC

“这是一本Ruby语言绝妙且详尽的入门指南。”

——Curtis Miller, Freebootr.com


和大多数人一样,我也是从Ruby on Rails开始结识Ruby语言的。从最早的那个“十分钟构建博客程序”的例子开始,完全地被吸引住了。从那时起,我在业余时间寻找很多资料和图书,学习这个惊艳的Web开发框架。但是在编写Rails程序的时候,其实我们对于Ruby语言知之甚少,学习资源都非常有限,基本上是从看Programming Ruby作为起点的。直到有一天,偶然看到了David A. Black(也就是本书作者)所编写的Ruby for Rails(R4R),才真正上道。终于在阅读该书的过程中,解决了许多编写Rails时对那些“魔法”的疑惑,也真正喜欢上了Ruby语言。转眼间就快10年了,身边那些曾经视Ruby为小众语言的人,后来很多人都开始喜欢上了Ruby,并逐渐在项目中越来越多地使用它。The Rails Way的作者Obie Fernandez在给The Ruby Way作序时写道:

在相当长的一段时间里,使用Ruby的人被置于主流之外,可是现在看来,我们才是主流。

看过一些关于Ruby的书,它们基本上大而全面,从语法基础到面向对象,从I/O编程到图形化接口,从线程到网络编程,从Web编程到测试框架等,却很少有书可以像本书一样,让Ruby初学者和爱好者真正理解Ruby的对象核心设计——对象个性化(object individuation)。理解对象个性化的设计有多重要呢?这是Ruby真正有别于其他语言的魅力所在,是Ruby语言动态特性的主要构成部分。由于它的动态特性,让程序员可以用它编写一门销售部门的技术小白都能学会的领域特定语言(Domain Specific Languages,DSL),然后生成一份漂亮的需求问卷,再稍加努力就可以生成一份非常有专业感的PDF格式版本。当然,这只是开个小小的玩笑,Ruby编写DSL的案例,知名的有Rspec或Cucumber这样的测试框架和Rake这样的make工具,它们都非常强大且易于编写。如果你需要找一本把Ruby基础中每个层面都讲得很细致且能把动态特性中的单例类、单例方法、回调机制、自省机制、可调用对象等晦涩难懂的内容都能讲得清晰明了的书,那么本书一定是不二之选。本书是R4R的一种延续,作者把R4R中关于Ruby的内容重新整理,并加入了许多Ruby的新特性,旨在将Ruby语言的基础用一本书全面概括,为读者将来的Ruby程序员之旅点起一盏航灯。

很荣幸能翻译这本书,这也让我多年的Ruby情结有了实现的机会。深深感谢本书的责任编辑杨海玲老师在翻译过程中给予的极大支持和帮助,同时感谢家人和朋友们提供的支持和鼓励。

最后,希望本书能让你轻松愉快地掌握Ruby语言,也希望你在成为Rubyist的同时能推荐更多的人学习这门优雅的语言。

谢谢!


钟凤鸣 海外程序员,常住新西兰,与本书第二译者互为连理。从事企业应用开发和手机APP开发多年,对技术充满热情,渴望不断地学习和运用喜欢的技术。

陈雪静 英语翻译硕士,程序员家属。受本书第一译者的影响,不仅研究英语语言学,也在业余学习计算机语言。


欢迎阅读本书。自第1版出版以来的5年间,Ruby语言有了许多变化和改进,最大的一次改进是在Ruby语言20岁生日(2013年2月24日)那天发布的Ruby 2.0版本。在2013年年末,准确地说是在圣诞节那天,Ruby 2.1版本发布了。这一版已涵盖了Ruby 2.1版本的内容。

本书一直深获好评。这本书满足了大量读者的需求,包括许多新学习Ruby的人和很多已经接触过Ruby但想详尽了解这门语言并确保自己真正理解了这门语言的人。我一直特别高兴的是,一些书评把阅读这本书的体验描述为与Ruby老师面对面。毕竟,我是一名Ruby教师,尽管教学和写作分属不同角色,但两者也并非完全不同。

Ruby语言的大部分没有改变,但还是有相当一部分出现了变化。这次第2版包含了许多新内容,并对原始文本做了大量的审阅和修订。和第1版一样,本书并不打算在Ruby语言上面面俱到,或作为一本标准库参考手册(这类书已有很多),而是对Ruby的对象模型、内置类和重要编程工具的关键环节进行深入的研究和论述。

我想对本书的所有读者表示热烈的欢迎,包括本书第1版的老读者和这本书的新读者。我希望并且相信读者会在本书中找到许多乐趣和惊喜。乐在其中吧!


2006年,Manning出版社出版了我写的Ruby for Rails: Ruby Techniques for Rails Developers。我撰写Ruby for Rails(大家所熟知的R4R)的目的是让Rails的开发者了解Rails开发者也就是Ruby开发者这一事实,同时也让Rails开发者扎实掌握Ruby这门语言。我选择将Ruby语言中的各主题收录到本书(或者选择不收录到本书)是依据我个人的判断标准:选择相对重要的内容给那些想正确和高效使用Rails从而学习Ruby语言的人。

对R4R的评论是非常好的。该书填补了一个空白:它不仅是一本纯Ruby的书,也不仅是一本纯Rails的书,而且是一本可以说是为Rails程序员做过“优化”的Ruby书。我很高兴许多人读完之后问我是否有计划写一本完整的只关于Ruby语言的书,并且鼓励我去写。

长话短说,于是我就写了这本书。

这是一本“纯Ruby”的书,写给所有对Ruby感兴趣的人。它是R4R的传承,但不完全是R4R的升级版。它更多地是改编。有些内容与R4R有重叠,但也有很多新内容(事实上比我原先预期的要多)。所有的内容,无论重叠与否,在第1版书交付印刷的时候都已经被润色和整理,并可以在Ruby 1.9.1版本上运行,这是本书付印时的最新(非常新)版本。

要知道,我的意思并不是说Rails开发者不用读这本书。恰恰相反,我高兴地看到,在R4R出版后的3年里,Rails开发者应该学习Ruby这一观念已被大众认可,许多通过学习Rails初次进入Ruby世界的开发者已对Ruby语言自身的魅力产生了兴趣。本书就是为他们而写的,也是为那些通过各种不同的途径发现Ruby的人而写的。

不论本书能带给你什么,我都希望你乐在其中。


首先要感谢所有我在第1版中感谢过的人。若没有全体编辑、制作人、审稿人、出版商和同事们,就不会有这本书。

对于第2版来说,我最要感谢的是开发编辑Dan Maharry,他的耐心、支持和指引让这本书走上正轨,否则不会有这本书。技术开发编辑Andrew Gibson扮演专家的角色,他用专业的挑剔眼光来看整本书,这一点对本书大有裨益。文字编辑Jodie Allen对文字的整体润色做出了巨大贡献。技术校对Deepak Vohra认真审查了示例代码,并及时发现了一些问题。校对Melody Dolab通读全文并做了修正。

在前期制作中,Kevin Sullivan保持每一件事都按部就班并按期完成。产品经理Mary Piergies再次用极高的专业性引导本书的完成。排版人员Dennis Dalinnik做得非常出色,一切都很顺畅。在本书的质检阶段,Katie Tennant提出了许多有价值的见解和建议。

一路走来,一些外部评审员提出了很多意见和批评,这一切使我在撰写第2版的时候比第1版更加精练,更具可读性。我要感谢Jason Brown、Marius Butuc、Hector Sansores、Jeffrey Schwab、Doug Sparling、Andrea Tarocchi、Ted Roche和William E. Wheeler。

在第2版写作期间,David Williams自始至终支持和鼓励我,是他让我坚持不懈并保持斗志。在此深表谢意。

和往常一样,我要感谢松本行弘(Matz)创造了美妙的Ruby语言。顺便提一下,若从松本行弘首次公开宣布这个项目之日算起,最近它刚刚过了21岁的生日(2014年2月24日)。让我特别高兴的是,本书第2版出版的时间碰巧大致与这美妙的里程碑吻合。


欢迎翻开本书。

Ruby语言由松本行弘(Matz)设计,是一门通用的、面向对象的、解释型的编程语言。Ruby最早是在1993年发布的。第一个发行的版本在1995年公之于众,并在20世纪90年代风靡日本。Ruby能够以相对少的代码完成较多事务,并且以优雅和视觉流畅的语法和风格著称,获得了许多赞誉。事实证明,Ruby在广泛的编程领域中,从服务器管理脚本到嵌入式设备集成,从Web开发到PDF文档处理,都是非常有用和高效的。此外,可能有人说Ruby编程技术性不强,但Ruby编程很有趣,它正是按这个思路设计的。正如松本行弘所说,Ruby为编程体验而优化。确实,因为许多程序员对松本行弘曾做过的同类语言的设计颇有好感,诞生于松本行弘“玩具项目”(pet project)的Ruby语言从一开始就获得了众多的关注。

关于Ruby的第一本英文书Programming Ruby(Dave Thomas和Andy Hunt)在2000年年底出版,并因此引领了一波日本之外学习Ruby的浪潮。自从“镐书”(Pickaxe book)(Thomas和Hunt编写的Programming Ruby的别名,源于书的封面插图)出版,Ruby在西方逐步普及。“镐书”第1版发行4年后,David Heinemeier Hansson发布了Ruby on Rails框架,并由此激发了全世界范围内学习Ruby的热情。自2004年以来,Ruby的使用率成指数倍增长,同时增长的还有Ruby的书籍、Ruby用户组以及Ruby相关的会议和其他活动。

我是一个Rails的开发者和爱好者。同时,我坚信,即使Rails从来没有出现过,Ruby最终也将被世界“发现”并达到目前Rails时代的规模。Ruby是一门令人非常愉悦和通用的语言,它将永远像拥有神秘面纱的宝石。我爱上Ruby已近乎14年了,我很高兴可以通过写作和教学将它介绍给许多人,并看到他们中的绝大多数也开心和满意地拥抱Ruby语言。

这就是我写这本书的初衷。本书的目的是让读者广泛和深入理解Ruby的工作机制和大量的Ruby技术工具,以及能在实际编程中使用的术语和习语。

本书第2版由15章组成,分为3个部分。

第一部分(第1章至第6章)包含Ruby语法以及许多构建关键理念和语意的内容:对象、方法、类和模块、标识符和其他。本书也讲述了Ruby编程的生命周期(如何准备、执行代码文件,并写出调用多个文件的程序),同时还有Ruby支持的经常使用的许多命令行工具,包括:Ruby的交互式解释器(irb)、RubyGems包管理器(gem)和Ruby解释器(ruby)。

第二部分(第7章至第12章)深入讲解一些主要的内置类(build-in class),包括字符串、数组、散列、数值、范围对象、日期对象和时间对象,以及正则表达式,也让读者深入了解各种内置工具的用途,以及使用的具体细节。同时也在探索如下问题的过程中构建读者对Ruby的基础认知:Ruby中的布尔逻辑、用于转换对象(如转换字符串到整型)的内置方法、用于处理集合类型(collection)和枚举(enumeration)的许多机制,以及比较对象唯一性和相等性的技术。还可以学到关于文件操作和控制台输入输出(I/O)及Ruby程序内部调用系统指令的方法。

第三部分(第13章至第15章)阐述Ruby的动态特性。在这个主题之下存在着很多子议题:其中一些关于元编程技术,包括Ruby运行时反射和对象自省机制,以及赋予对象个性化行为的方式,还有函数、线程、其他可运行可执行对象的处理方法。本书的这一部分还介绍了从Ruby程序中调用系统指令的技术,包括Ruby中由事件触发的运行时钩子(hook)和回调(callback),如程序调用不存在的方法时和通过如类继承及方法定义时的拦截事件。

Ruby语言有完整的系统性,以严格的顺序阅读方式阐述这样的一个系统是一项挑战。撰写本书要应对的挑战是把学习过程看作是一个渐开螺旋,总是建立在熟悉的知识基础上但又对未知充满渴求。有时,读者要为将来的主题给出足够的留白,那样就能够把目前的主题学得更为深入。之后,当必要的知识已储备完成,就可以回到之前的留白去完成它。本书的设计是为了让读者获得尽可能多的素材,这一目标与真正掌握和持续理解语言的运行机制,从而打下坚实基础的目标一致。

本书第2版针对读者进行了优化,其读者对象是有过编程经验的,或许甚至是有过Ruby编程经验并想要学习更多Ruby语言编程技术的人。书中不仅有具体的技术(尽管书中包含的是大量的技术内容),而且也有构成Ruby的设计原理。我对读者的能力深信不疑,也确信读者不会每写一行代码都要在脑海中进行一次论证,而是会了解如何最大限度地理解编程语言,并且知道出现问题时如何分析。

对一些有针对性的读者,我需要正视一些问题,因为本书收录的一些入门性的专题和技术,对于有经验的开发者来说是很熟悉的。我尽力满足这部分读者的喜好,质疑的声音总是会很快出现,而我相信不时地用几句话解释一下术语,就可以让读者感觉到极为不同的舒适感和亲和力。假如读者是一个经验丰富的程序员,看了几页后发现这本书是填鸭式的,那么请原谅,毕竟我的初衷是好的。

同样的道理,如果读者是第一次涉足编程,准备主动地做一些额外的“家庭作业”,并以此获得编程能力的大幅提升,那么务必要尝试一下本书。本书没有专门介绍编程,而是让读者置身于实践之中,包括创建和运行程序文件,并从基础出发去阐述Ruby语言。

本书第2版是一本重要的全方位关注Ruby语言的书,但它并不是一本完全的语言参考手册。有一些核心类(core class)很少提及或未提及,书中讨论的标准库的包数量有限,这是设计使然。读者并不需要本书详细地说明怎样使用每一个标准库API,我也不会这样做。在所有的可能中,读者可能需要的是有人可以准确地解释class << self的含义,或者为什么两个实例变量分写在两行却不是同样的变量,或者单例方法和私有方法之间的差别,还有什么是枚举器(enumerator)以及它和迭代器(iterator)的区别。读者需要知道上面所说的种种,也需要看到它们所起的作用并开始使用它们。当然,也有必要为了工作中使用Ruby而去深入地了解标准库,我确实鼓励这样做。我的目的是让读者对本书有着独特的和不同程度的理解。

本书第2版覆盖了Ruby语言2.1版本的内容,这也是写本书时的最新版本。Ruby 1.9版本仍然在广泛使用中,但我预测它将不会使用太长的时间。如果读者仍然在使用Ruby 1.9版本,也将会从书中得到很多有价值的信息,但在不远的将来有可能尝到Ruby 2的不同“风味”。

在正文中,Ruby变量和常量的名称都使用等宽字体。当类和模块的名称表示直接引用现有类或模块的对象时,也使用等宽字体。例如,“下一步,我们将重新打开Person类定义块。”凡类和模块的名称用在更为狭义的地方,这个名称就使用正常字体,如“现在我们需要一个Array的实例”。不管在什么样的情况下,读者能够通过上下文,对本书中出现的类、模块及Ruby的其他实体的命名加以区分。

本书中示例所使用的源码可以从如下地址下载:www.manning.com/black3或者www.manning.com/TheWellGroundedRubyist-SecondEdition。

直接用于执行的程序和作为命令行的程序,如rubyrails,它们的名称使用等宽字体。

斜体或星号用作通配符表达式。例如,to_*可能指向Ruby一般类型的方法,包括to_ito_s,而position_match可能相应指向的方法却是post_match或者pre_match

可以把书中的代码示例放到一个文本文件中,然后用ruby命令独立运行它们,也可以把它们输入交互式Ruby解释器(irb)中运行。在第1章中,会学到这些技术。随着对本书的深入阅读,我们将假定读者可以独立运行程序,书中若没有给过对文件名的建议(或者读者喜欢不同的名称),读者也可以为示例文件命名。

书中大量的例子都是以irb会话的形式展现的。读者在书中看到的代码,是在用irb运行代码的实时会话中剪切粘贴过来的,所以很容易辨认出这样的格式(特别是读者开始使用irb的时候)。这样的表达方式对于较短的代码片段和表达式来说尤其适合,并且无论读者输入什么(它甚至像是一个计算器),irb总是会输出执行的结果,这可以减少为了看到输出结果而使用print指令的次数。

在其他的代码示例中,代码的输出结果被安排在示例之后分别印刷,或者伴随代码示例印刷(清晰地标注为输出部分),或者嵌在代码段之后的叙述之中。

在一些示例旁会伴随出现标有数字的球形符号。这些球形符号关联到之后叙述的具体要点,并让读者可以在叙述中快速回查。

命令行程序的调用使用美元符号($)作为提示符,它通常是类UNIX环境中普遍使用的shell提示符。这些命令大多数可以在Windows上运行,只是提示符可能会不同(在所有的系统环境中,命令的可用性总是依赖于在系统环境变量中设置相对路径)。

尽管在其他领域中,我遵从W3C的指南使用“Web”,在这里我使用“Web”来表示万维网。

购买本书第2版后,读者可以免费访问Manning出版社运营的私有Web论坛,在那里可以评论本书、咨询技术问题、得到作者和其他用户的帮助。访问论坛和订阅论坛,请浏览如下任意网站:

这个页面介绍了注册后如何访问论坛、可以得到什么帮助以及论坛上的行为规则。Manning承诺为读者之间、读者与作者之间提供一个可以对话的场所,但因作者在论坛上的贡献都是自愿的(不收费的),所以不会强制作者参与。为使作者感兴趣,提高其参与度,我们建议读者提一些具有挑战性的问题。

只要本书依然在售,读者就可以从出版社网站访问作者在线论坛(The Author Online forum)和之前讨论话题的存档文件。


本书封面上的插画是一位法国贵族或者说是一个法国贵妇人。这张插画取自Sylvain Maréchal在1805年印刷的关于地域服饰风俗的4部画卷纲要。这本书于1788年(即法国大革命前一年)在巴黎首次发布。每一张插画都手工上色。

Sylvain Maréchal色彩缤纷的图集唤醒我们对近200年前世界不同地域文化独立性的思考。他们曾彼此隔绝,人们说着不同的方言和语言。从乡下到市区,通过他们的着装很容易辨认出他们生活的地方、他们经营的生意以及身份。时过境迁,那时如此丰富的地域着装规范以及多样性已不复存在。现今就连不同的国家都很难从服饰上进行分辨,更不必说城市和地区了。或许,我们用文化的多样性换取了更为丰富多彩的个人生活,这无疑是一种更为多元化的,也是更为快节奏的科技生活。

现今,计算机图书层出不穷,Manning出版社用两个世纪之前富有多样性地域生活的插画作为书的封面,以此来庆祝IT行业日新月异的发明和创造力,并让Sylvain Maréchal的插画得以重现。

Sylvain Maréchal(1750—1803):法国散文作家、诗人、哲学家。维基百科http://en.wikipedia.org/wiki /Sylvain_Mar %C3%A9chal。——译者注


本书这一部分的目标是让读者建立一个广泛而实用的基础,并在进一步探索第二部分和第三部分之前牢固掌握它们。本章是引领读者进入Ruby知识的一章,通过第1章的学习,就可以从容地运行Ruby程序,并对Ruby典型安装方式的设计有良好的认识。从第2章开始,将深入了解Ruby语言的细节。Ruby是一门面向对象的编程语言,越早深入了解Ruby处理对象的方式越好。因此,对象既成为了引入语言讨论(和读者对它了解)的一种方式,也是贯穿下一步深入主题和技术的主线。

对象(object)由类(class)创建,本书将在第3章学习类的工作原理。紧随类之后的第4章中,将会学习到模块(module)。模块允许通过把一些对象分解为可重用的代码单元的方式,对类和对象进行微调。为了理解Ruby程序,需要知道Ruby中当前默认对象(default object)的概念,即众所周知的关键字self。在第5章中,伴随对Ruby变量可见度(variable visibility)和作用域(scope)的处理,将深入了解“self”的概念。

在第6章中,也就是第一部分的最后一章,将会学习到如何在Ruby程序中使用控制流,即如何运用条件(if)逻辑驾驭Ruby解释器,如何通过代码进行反复循环,甚至如何在错误发生的时候打断正常程序的执行。在第6章的最后,将用Ruby语言的方式进行思考,去编写和开发程序。

这一部分的标题是“Ruby语言基础”,这显然使人想到后面的内容是建立在这一部分之上的,它也的确有这样的作用。但是这并不意味着第一部分的内容不重要。一旦读完第一部分这6章的内容,将会学习到真实的Ruby技术、真实的代码以及每次编写和执行程序都要用到的知识,但并不是说读完第一部分就可以了,本书后面还有更多的Ruby知识。


本章主要内容

本书的内容是Ruby基础,而本章是基础中的基石。本章的目标是让读者在开始学习Ruby之前掌握足够的知识和技巧。

接下来读者将看到Ruby的基本语法和技术,以及Ruby的运行机制:如何写一个程序,怎样使用Ruby运行程序,以及如何把一个程序分写到多个文件中。此外,读者还将学习到一些开关(switch)的用法,即它们如何改变Ruby解释器(名为ruby的程序,用于执行用Ruby语言写的程序文件)的作用,也会学习使用一些重要的辅助工具,让读者的Ruby程序员生涯更加轻松和高效。

本章将Ruby领域的观点分为以下3个基本层次。

这3个部分在一个系统中环环相扣,因此在本书中它们的内容会相互贯穿,不过在本章中会尽量分开讨论。尽管如此,这3个部分的内容都会贯穿在书的每一章中。

Ruby,ruby,还是RUBY?!

Ruby是一门编程语言。我们会谈论“学习Ruby”,还会问一些问题,比如“你知道Ruby吗?”ruby是指一个计算机程序,特指Ruby的解释器,它可以读取并运行程序。可以看到这个命名方式在一些文章中出现,如“你用ruby运行我的文件,但什么也没发生。”,或者“ruby可执行文件的完全路径是什么?”最后是RUBY,准确来说,没有这样的写法。Ruby不是一个缩略语词汇,所有字母都大写的拼写方式向来都是错的。人们在对待Perl语言的时候也出现过同样的错误,或许是因为他们看到了如BASIC和COBOL这样的拼写方式,但Ruby不同。一般用“Ruby”来表示编程语言,用“ruby”来表示Ruby的解释器。

第1章不是只为服务于其他章节而存在的,它也有自己存在的价值:学习真正的Ruby技术和这门语言设计中的要点。其目标是为了引导和启发读者,但即使如此,学习过程还是会深入Ruby语言的一些关键层面。

本节的目标是让读者开始接触Ruby。这里采用广度优先的方法:大致围绕语法学习、代码编写、程序运行这样一个循环过程展开。

说到这里,读者需要在自己的电脑上安装好Ruby。书中的例子都使用Ruby 2.1.0编写。还需要准备一个文本编辑器(任何偏好的编辑器都可以,也可以用纯文本编辑器,但文字处理软件不行)和一个存放Ruby程序文件的目录(亦称文件夹)。可以命名目录为rubycode或者rubysamples,无论什么名字都可以,只要能够区别于其他工作区并方便地找到练习程序文件即可。

交互式Ruby控制台程序(irb)是最好的朋友

随Ruby发布的irb实用工具,是一个Ruby命令行工具,irb使用的广泛程度高于Ruby解释器本身。启动irb之后,键入Ruby代码,它将执行代码并输出结果值。

在命令行中键入irb,然后输入在文中所见的示例代码。例如:

打开irb会话意味着可以随时测试任意数量的Ruby代码段。大多数Ruby程序员都发现irb是不可缺少的,而且本章中的一些示例也是使用irb运行的。

读者将看到下面irb的示例使用了命令行选项,它的输出结果更易于阅读。

运行irb时加入此选项或者不加,就可以看到--simple-prompt选项的效果。正如所见,这个简单的提示符选项将使屏幕更简洁明了。默认的(非简单的)提示符显示了更多的信息,如在交互会话时的行号统计。但从众多的示例可以看出,简单的提示符已足够使用。

因为irb是一个用于运行Ruby语言的命令行工具,所以直到1.4.2节才会详细讨论它。如有需要,可以转到那一节去看一下,这是最直接的方式。

完成Ruby的安装,并创建好工作目录的,就继续学习Ruby吧,这样我们就能分享Ruby学习和探索中的见地。掌握Ruby的语法将会是一个良好的开端。

下面3个表总结了Ruby的一些特性,这对于理解本章的例子和开始体验Ruby语言大有益处。不必记住它们,只要看一下并在稍后用到的时候回查即可。

表1-1包含了Ruby的一些基本运算。表1-2中介绍了获取基础键盘输入、将输出发送到屏幕以及基本的条件语句。表1-3简要描述了Ruby的特殊对象和注释的语法。

表1-1 Ruby的基本运算

操  作

示  例

注  解

算术运算

2+3(加法)
2–3(减法)
23(乘法)
2/3(除法)
10.3 + 20.25
103 - 202.5
32.9 10
100.0 / 0.23

所有的运算都使用整型或浮点型。如例子中所示,混合使用整型和浮点型数值进行运算,其结果为浮点型



注意:需要使用0.23而不是.23

赋值

x=1
string = "Hello"

本操作将一个对象(右边)绑定到一个局部变量(左边)之上。与此同时,把对象看作是用变量表示的一个值

值比较

x == y

注意:使用两个等号(不同于赋值使用一个等号)

字符串到数值的转换

x = "100".to _ i
s = "100"
x = s.to _ i

为了算术运算的顺利执行,必须保证使用的是数字而不是字符构成的字符串。to_i用于执行字符串到整型的转换

表1-2 Ruby的基本I/O(输入/输出)方法和流控制

操  作 示  例 注  解
打印到屏幕 print "Hello"
puts "Hello"
x = "Hello"
puts x
x = "Hello"
print x
x = "Hello"
px
如果字符串的行尾没有包含换行符,puts就会添加一个,但print不会
print会精确打印内容并让光标留在末尾(提示:在某些系统平台,在程序输出的末尾会自动换行)
P会输出一个审查字符串,它通常会包含一些额外的输出信息
获取键盘单行输入 gets
string = gets
直接将输入的一行赋值给变量(第二个例子中的变量string
条件语句执行 if x == y
 puts "Yes!"
else
 puts "No!"
end
条件语句总是以单词end结束(更多细参见第6章)

表1-3 Ruby的特殊对象和注释

操  作

示  例

注  解

特殊值对象

true
false
nil

对象truefalse通常用于返回条件表达式的值。对象nil是“nonobject”的一种,表明值或者结果的缺失。false和nil使得条件表达式失败,所有的其他对象(包括true,当然也包括0和空字符串)使得其成功(更多细节参见  第7章)

默认对象

self

关键字self引用默认对象。self是一个依赖于运行时上下文,由不同对象扮演的角色。没有指定调用者的方法,调用的时候会默认为被self调用(更多细节参见第5章)

代码中的注释

# 一个注释
x = 1 # 一个注释

注释部分,会被编译器忽略

以上摘要表中已经包含了许多Ruby的基础和语法。读者需要能够辨认出Ruby标识符(identifier)的几种不同写法,尤其是对Ruby中的对象和方法调用有一个感性认识。我们稍后将会谈论这些内容。

Ruby的标识符类型很少,一眼就能辨认和区分它们。标识符体系如下。

这是一个很小的体系,很容易掌握,这一节将讨论它们。记住本节的目标是学习辨认不同的标识符。本书后面将学习如何使用和使用它们的时机。这只是标识符知识的第一课。

1.变量

局部变量以小写字母或者下划线开头,包含字母、下划线或数字。xstringabcstart_valuefirstName都是有效的局部变量命名方式。然而,值得注意的是,在组合多个单词以命名局部变量时,Ruby的约定是使用下划线作为命名规范,而不使用驼峰命名法,如使用first_name而不使用firstName

实例变量为独立的对象存储信息,它通常以一个单独的符号(@)开头,后面的字符使用与局部变量相同的命名规则,如@age@last_name。尽管局部变量不能以大写字母开头,但是实例变量可以在@符号之后的第一个位置使用大写字母(但不能使用数字)。但是通常来说,@符号之后还是使用小写字母。

类变量在每一个类层级上存储信息(同样,现在也不用担心它的语义)。它与实例变量使用相同的命名规则,只有一点不同,它以两个@符号(@@)开头,如@@running_total

全局变量可以通过它的美元引导符号($)辨认出来,如$population。跟在$符号之后的语句不使用局部变量的命名规则。有一些全局变量名为$:$1$/,还有$stdin$LOAD_PATH。但只要以$符号开头,它就是一个全局变量。这些非字母的标识符是预定义的,因此不必担心其中的标点符号是否合法。

表1-4总结了Ruby变量的命令规范。

表1-4 总结Ruby变量命名规范

变 量 类 型

Ruby规范

非 规 范

局部变量

first _ name

FirstName 、 _ firstName 、 __ firstName 、 name1

实例变量

@first _ name

@First _ name 、 @firstName 、 @name1

类变量

@@first _ name

@@First _ name 、 @@firstName 、 @@name1

全局变量

$FIRST _ NAME

$first _ name 、 $firstName 、 $name1

2.常量

常量使用大写字母开头。AStringFirstNameSTDIN都是有效的常量命名。在Ruby命名规范中,如遇到命名多词组合的常量时,可以使用驼峰命名法(FirstName)也可以使用下划线分隔且所有字母大写(FIRST_NAME)的方式。

3.关键字

Ruby拥有很多的关键字,它们是预定义的保留词,与特定编程任务和上下文关联。关键字包括def(用于方法定义)、class(用于类定义)、if(条件执行)和_FILE_(当前被执行文件的名称)。关键字大约有40个,通常是简短的、单一词汇(与下划线组合多单词方式相反)的标识符。

4.方法名

Ruby中的方法命名遵从与局部变量相同的规则和约定(除了以?!=结尾的符号,其重要作用稍后会讲述)。这是一种设计理念:方法并不因其自身作为方法而被人关注,而是简单地作为提供值的表达式融入到程序的结构中。在一些上下文中,很难一眼就区分出一个表达式是一个局部变量还是一个方法名,这一切源自设计,是有意为之。

讲完方法,现在已经有了一张Ruby标识符的“路线图”,让我们谈一下编程语言的语义,尤其是对象及其方法的重要作用。

Ruby把所有的数据结构和值都看做对象,从整数和字符串这样简单的标量(原子的)值,到数组(array)这样的复杂的数据结构一概如此。每个对象都能响应一组特定的消息,对象能够接收的每个消息直接对应一个方法——有名称的、可以被有执行能力的对象触发的可执行例程。

对象也可以用字面量构造器表示,如字符串用双引号,或者已绑定值的变量。消息通过特殊的点运算符(.)送达:点右边的消息被发送到点左边的对象上。(另外,有许多特殊的给对象发送消息的方式,但是点是最常用和基础的方式。)参见表1-1中的示例:

点(.)意味着消息to_i被发送给字符串对象"100"。字符串对象"100"作为消息的接收者被调用。也可以说是方法to_i被字符串对象"100"调用。方法调用的结果是生成整数100,然后作为赋值运算的右表达式赋值给变量x

为什么使用两种术语?

何苦为该说“发送to_i消息”还是说“调用to_i方法”而烦恼?对于同一操作为什么有两种不同描述?因为它们不完全相同。大多数时候,发送消息给接收的对象,对象就会执行对应的方法。但有些时候是没有对应方法的,对于点右边的任意标识符,并不能确保接收者拥有的方法与发送的消息相匹配。

这听起来有些混乱,其实不然。因为对象可以拦截未知的消息并使它们拥有具体含义。例如,Ruby on Rails Web开发框架大量使用了如下的技术:发送未知消息到对象并拦截那些消息,然后能够在使用当前数据库表的列名作为动态条件的情况下顺畅运行。

方法可以带有参数,这个参数同时也是对象。(虽然有些用于创建和操作对象的语法结构本身不是对象,但在Ruby中几乎所有一切都是对象。)下面是一个带有参数的方法调用:

字符串对象100调用方法to_i并传递参数9,生成一个九进制的100所得到的十进制整数,因此x现在等于十进制的81。

这个例子也同时展示了使用圆括号包含参数的方式。这些圆括号通常情况下是可选的,但是在大多数复杂的情况下,为了避免语法上的歧义,圆括号的使用是必要的。大部分程序员都尽可能在方法调用时使用圆括号,这样做是为了避免歧义。

完整的Ruby程序是由对象以及发送给对象的消息所组成。作为一个Ruby程序员,大多数时间要么是定义对象所能完成的任务(定义方法),要么是请求对象完成这些任务(给对象发送消息)。

接下来在书中将会深入地讲述这些内容。再说明一下,这一段简短的概述是引领读者进入Ruby世界的其中一步。当看到点出现在某些令人费解的位置时,应该把它理解为一个发送给对象(左边)的消息(右边)。同时,也该记住一些裸词(bareword)风格的方法调用方式,例如puts在如下示例中的调用方式:

这里尽管缺少消息发送所需要的点以及该消息的显式接收者,却依然发送了消息puts并传递了参数"Hello."给一个对象:默认对象self。在程序运行期间,虽然作为self的对象会通过特定规则发生改变,但self总是被预定义好的。在第5章中将会对self进行详细阐述。现在,只要知道像puts这样的裸词的方法调用方式即可。

对象的概念在Ruby中是最为重要的,与此紧密相关并扮演重要角色的概念是(class)。

用类解释对象的由来

定义了一组行为和功能,每一个对象是一个具体类的实例。Ruby提供了大量的内置类,它们代表了重要的功能数据类型(如StringArrayFixnum)。每次创建一个字符串对象的同时,就创建了一个String类的实例。

用户可以编写自己的类,甚至可以修改已经存在的Ruby类。如果不喜欢字符串或者数组的行为,可以修改它。这看起来虽然不好,但是在Ruby中是允许这样做的。(第13章中将描述修改内置类的利弊。)

尽管每一个Ruby对象都是类的一个实例,但是类的概念却不如对象的概念那么重要。那是因为对象可以发生改变,它可以获得在类中没有定义过的方法和行为。类负责将对象变为实际的存在,这就是耳熟能详的实例化(instantiation)过程。而对象在实例化之后,就进入了自己的生命周期。

对象有能力包含一个在类中没有定义的行为,这是设计Ruby作为一门编程语言时最为核心的原则之一。正如读者所猜测,书中将在不同的上下文中不断地回到这一点来讨论。对目前而言,只要意识到尽管每个对象对应一个类,但对象的行为不由对象的类唯一决定即可。

了解了Ruby的知识(疑惑之时回看一下这些内容)后,让我们尝试着运行一个程序吧。

在本节中,将会在之前创建的Ruby示例程序目录中创建一个程序文件。第一个程序是一个摄氏—华氏度转换工具。

注意


当然,在真实场景中,温度的转换使用的是浮点数。而这里在输入输出时使用整数,主要是为了专注于程序的结构和程序的执行。

这个例子将被反复提到,并根据本书的需要进行添加和修改。它遵循如下的迭代过程。

第1个版本很简单,仅关注文件创建和程序运行的过程,而不用深入程序逻辑的细节。

创建第一个程序文件

使用一个纯文本编辑器,输入代码清单1-1所示的代码到一个文本文件并保存为c2f.rb到示例目录中。

代码清单1-1 简单的专用摄氏—华氏度转换工具 (c2f.rb)

注意


根据用户的操作系统的不同,Ruby程序文件有可能仅用文件名或一个短名称就可以独立运行,并不需要使用文件扩展名。尽管如此,请记住,.rb的文件扩展名在一些情况下是强制的,这主要是涉及拥有多个文件(后面会详述)的程序和有文件间相互查找机制的程序。在本书中,所有Ruby程序文件名都以.rb结尾,这是为了确保示例程序可以在尽可能多的平台上运行,同时尽可能少地对系统进行管理干预。

现在,已经有了一个完整的(虽然很小)Ruby程序,可以运行它了。

运行一个Ruby程序需要给Ruby解释器传递程序的源码文件(或者多个文件),这个Ruby解释器名为ruby,后面会依次解释。在提供一个程序给ruby而不是请求Ruby运行程序之后,它会检查程序代码的语法错误。

1.检查语法错误

如果在转换公式中使用31替换32,就会发生一个程序性错误。Ruby还是会适时地运行程序并给出有缺陷的结果。但是假如程序的第2行中不小心遗漏了右圆括号,那就是语法错误,Ruby将不能运行这个程序。

(错误出现在第5行,即程序的最后一行,因为Ruby一直在耐心等候右圆括号出现,结果却没有。)

Ruby 解释器提供一种便捷的方式来检查语法错误而不必运行程序。它会读取文件并指出语法是否有错。为了检查源文件的语法错误,可以这样做:

命令行中的-cw标志(flag)是两个标志的简写,它们分别是:-c-w。标志-c意味着检查语法错误。标志-w可以激活高级别的警告:如果程序都合乎Ruby语法,Ruby就不会发出警告,除非有比语法更值得商榷的理由。

假如输入的文件正确,将在屏幕上会看到如下信息:

2.运行程序

为了运行程序,再次提供源文件给解释器,但是这一次不用加入-c-w标志。

如果一切顺利,将可以看到计算的结果输出如下:

计算的结果正确,但是计算的结果超过了3行,这看起来不够好。

3.温度转换器的第二次迭代

问题要追溯到puts命令和print命令的区别。假如字符串没有以一个已经存在的换行符结束,puts命令会在它打印的字符串尾部插入新换行符。相反,print打印字符串之后就停止了,它不会自动跳转到下一行。

为了修正这个问题,把前两行的puts命令改为print

(注意,is后面的空格,它是为了确保在is和数值之间有一个空格。)现在输出的是:

puts是“put(就是print)string”的缩写。尽管put没有直观的表示会调用换行符,但是puts会这样做:如同print,打印用户的数据,之后自动地转到新一行。假如让puts打印已经以换行符结束的一行,它不会再次添加换行符。

假如读者已经在其他编程语言中使用过打印的工具,而这些工具没有自动添加换行符(如Perl语言的print函数),那么可以自己编写类似Ruby中的实现,一个能打印值并添加换行符的工具:

尽管如此,大可不必这样去做,puts已经实现了。习惯使用puts吧,并在这个过程中遵循使用其他的Ruby习语和约定。

警告


在一些操作系统平台中(尤其是在Windows中),程序运行的结尾会打印输出额外的换行符。这意味着实际上print已经代替了puts,而puts很难被系统检测到。意识到这两者的区别,并在最常用的场景中使用其中一个,可以充分确信得到所期望的结果。

看一下屏幕的输出,接下来将扩展一点I/O领域的知识,包括键盘的输入和文件的操作。

Ruby提供了很多在程序执行过程中读取数据的技术,包括从键盘读取和从磁盘文件读取。它们有许多用途:不仅仅在编写每个应用程序的过程中会用到,在编写维护、转换、管理或者操纵用户的工作环境的代码时也几乎一定会用到。本章中包括了一些输入处理的技术,更多关于I/O操作的技术详见第12章。

1.键盘输入

反复执行100摄氏度等于212华氏度的程序,其价值是有限的,更有价值的程序则是可以自由指定华氏温度并获得对应的摄氏温度。

修改程序完成如上的功能需要几个步骤,分别需要使用表1-1和表1-2中提及的方法gets(获取键盘输入的一行数据)和to_i(转换为整型),读者应该已经熟悉它们其中的一个。由于这不仅仅是修订版本而是一个新程序,所以把代码清单1-2中的代码版本放到名为c2fi.rb的新文件中(i意味着交互)。

代码清单1-2 交互式温度转换器(c2fi.rb)

下面为新程序的一组运行结果:

简化代码

将代码清单1-2中代码的输入、计算、输出操作进行简化。简化重写后如下:

虽然这个版本确实减少了变量使用,但是会要求阅读代码的人接受这组有些密集(但是简短)的表达式。任何既定的程序通常都需要在长代码(也许更清晰)和短代码(也许有点晦涩)之间进行抉择。而有时候,短代码则更为清晰,这就是Ruby的编码风格。

如果不深究更多细节,现在这个版本已经是一个通用的摄氏度转华氏度的解决方案。接下来,让我们学习文件的读取。

2.读取文件

从Ruby程序中读取文件并不困难,至少在大多数情况下,比键盘输入还要容易。温度转换器的下一个版本将从一个文件中读取一个数组,然后从摄氏度转换为华氏度。

首先,创建一个文件并命名为temp.dat(温度数据),同时包含一个数字:

现在,创建第三个程序,命名为c2fin.rb(in意为文件输入),如代码清单1-3所示。

代码清单1-3 使用文件输入的温度转换器(c2fin.rb)

这一次,示例运行的输出结果如下:

自然地,如果在文件中改变数字,结果将会不同。那么,怎样将计算的结果写入文件中呢?

3.写入文件

从最简单的操作来说,文件写入要比文件读取复杂一些。正如代码清单1-4所示,执行写入文件的操作时,主要的额外步骤是要指定文件的模式,在这个例子中是w(意为写入)。保存代码清单1-4所示的这个版本,命名为c2fout.rb并运行它。

代码清单1-4 使用文件输入的温度转换器(c2fout.rb)

调用方法 fh.puts Fahrenheit的作用,是将 Fahrenheit的值输出到由fh对象进行写入处理的文件中。如果检查文件temp.out,无论输入什么数字,都可以看到转换好的华氏温度值。

作为练习,可以尝试着把前面的例子进行合并,让它从一个文件读取数字,转换为华氏度,之后把结果写入不同的文件中。在适时引入一些Ruby语法的同时,下一节会检验Ruby的安装,然后很快还会依次看到Ruby如何管理扩展和库。

在系统上安装Ruby意味着在许多磁盘目录中安装了Ruby语言的库和支持文件。大多数时候,Ruby都知道如何找到其所需要的这些目录而不用弹出提示。但是了解Ruby安装的知识对了解Ruby本身大有益处。

查看Ruby的源代码

除了Ruby安装目录体系之外,Ruby的源代码目录也安装好了。如果没有,可以到Ruby的主页中下载。源代码目录中包含了许多在最终安装中出现的Ruby文件和许多已编译为目标文件并安装好的C语言文件。另外,源代码目录包含了一些如ChangeLog和软件授权文件这样的资料类型文件。

Ruby安装文件的位置很容易获取。要得到这些信息,只需要在irb会话中加载名为rbconfig的Ruby库。rbconfig是一个接口,通过它可以得到关于Ruby安装的许多内部编译的配置信息,可以通过irb的命令行标志-r和指定的包名调用irb去加载它:

现在可以获取这些信息了。例如,可以找到Ruby可执行文件(包括ruby和irb)的安装目录:

RbConfig::CONFIG是一个引用散列(hash,是一种数据结构)的常量,用于在Ruby中保存配置信息。字符串"bindir"是散列的主键。用"bindir"这个主键查询散列将返回对应的值,这个值是安装二进制文件的目录名。

其余的配置信息也使用相同的方式获取:通过散列的主键访问配置信息中的值。如果要获得其他安装信息,在irb命令中替换bindir为其他词语。但是每次都要遵循相同的基本原则:RbConfig::CONFIG[术语]。表1-5概括了这些术语及其指向的目录。

表1-5 关键的Ruby目录和它们的RbConfig术语

术  语

目 录 内 容

rubylibdir

Ruby标准库

bindir

Ruby命令行工具

archdir

特定架构的扩展和库文件(已编译,二进制文件)

sitedir

用户自己或第三方扩展和库文件(用Ruby编写)

vendordir

第三方扩展和库文件(用Ruby编写)

sitelibdir

用户自己的Ruby语言扩展(用Ruby语言编写)

sitearchdir

用户自己的Ruby语言扩展(用C语言编写)

这就是对Ruby主要的安装目录和其包含内容的一个概述。此刻不必记住它们,但要意识到需要时如何找到它们(或者好奇时浏览一下并查看Ruby的代码示例!)。

在rubylibdir目录中,可以看到用Ruby编写的程序文件。这些文件提供了标准库的功能,如果需要它们提供的功能,可以在程序中请求(require)它们。在本目录中可以找到以下文件。

在标准库中有一些库,如drb,由多个文件构成。可以看到目录中有一个drb.rb文件,并且整个drb子目录包含了drb库的所有组件。

浏览rubylibdir子目录能够对Ruby提供的编程工具所能完成的任务有一个感性认识(也许一开始就是颠覆性的)。大多数程序员只使用了这些工具的子集,但这些巨大的编程库集合的子集也已经能够提供许多功能。

通常archdir目录位于rubylibdir下的第一级目录中,它包含了特定架构的扩展和库文件。通常在目录中,这些文件都是以.so、.dll、.bundle(依赖于硬件和操作系统)为文件扩展名的。这些文件是C语言扩展:它们是二进制文件,是运行时可加载的文件,由Ruby的C语言扩展代码生成,并在Ruby安装过程中编译成为二进制格式。

如在rubylibdir目录中的Ruby语言程序文件,archdir目录中的文件包含了能够加载到用户程序的标准库组件。(除此之外,还有一些rbconfig的扩展文件,这些扩展可以使用irb命令去发现它们。)这些文件不是用户可读的,但是Ruby的解释器可以读懂它们。从Ruby程序员的视角来说,由于它们都被编译为了二进制格式文件,所以所有的标准库使用都是一样的,不管它们是用Ruby编写的还是用C语言编写的。

安装在archdir目录的文件,每个平台安装的都不相同,它们依赖于其被编译的扩展。这个扩展又反过来取决于由个人请求编译的内容和Ruby能够编译的扩展所组成的代码库。

在Ruby安装目录中包括一个名为site_ruby的子目录,它用于存储用户和系统管理员安装的第三方扩展和库文件。该目录中可能包括了用户所写的程序,还有一些从其他网站下载的工具包,以及Ruby库文件的存档。

site_ruby目录包含Ruby语言和C语言的不同子目录(是RbConfig::CONFIG中不同的两个项,分别为sitelibdir和sitearchdir),就这个意义而言,其与Ruby主安装目录并存在一个目录下。当用户请求一个扩展,Ruby解释器检查site_ruby下的子目录,也同时检查主rubylibdir目录和主archdir目录。

与site_ruby目录并存的是vendor_ruby目录。第三方的扩展都安装于此。vendor_ruby目录首次出现是在Ruby1.9中,从这两个目录中获得的包仍然在不断发展中。

RubyGems实用工具是打包和发布Ruby库文件的标准方式。当用户安装gems(被称为包)时,未绑定的库文件则会放置于gems目录。这个目录没有在配置数据结构(RbConfig::CONFIG) 中列出,但是通常都和site_ruby在同一级目录。假如读者找到了site_ruby,便可以看看gems目录中还安装了什么。在1.4.5节中将会了解更多关于gems的知识。

在这一节中,学到了Ruby调用扩展的机制和语义,这也是编写和安装扩展时需要用到的知识。

本节的要点并不是关于Ruby标准库的参考。曾在引言中解释过,本书的目标不是编写一本Ruby语言的参考文档,而是教会读者使用Ruby语言并掌握它,并最终拓宽视野。

相应地,本节的目标是讲述扩展的工作方式,即如何使用Ruby运行这些扩展、它们之间技术实现的不同,并最终能让用户自己编写扩展和库文件的扩展架构。

随Ruby发布的扩展通常全部作为标准库来引用。标准库包括为不同项目和任务所提供的扩展,如数据库管理、网络、数学领域、XML处理等。标准库精密的结构每次改变,哪怕只有一点,也都要随着Ruby新版本而发布。使用最多、最广泛的库,已经证明了其存在的价值,所以通常都趋于稳定。

使用扩展和库的关键是require方法,与之密切相关的是load方法。这些方法让读者可以在运行时加载扩展,包括自己编写的扩展。我们将通过加载内置的扩展来学习它们并拓展我们的视野。

可以手动把程序存储在单一文件中,但如果有成百上千行或者成千上万行的代码,这将是一种负担而不是优势。尽管如此,可以将程序分解为能运行的不同文件。在Ruby中使用requireload方法将会使得这一过程变得容易。这里先阐述load的使用,它是两个方法中设计得最简单的一个。

功能、扩展,还是库?

用户在运行时加载到程序中的程序代码有许多不同的名称。功能(feature)是最为抽象的,很少听到过有人说“请求一个功能”(requiring a feature,这里使用require)这样特殊的使用方式。库(library)是更为具体和通用的。它意味着存在一组真实的易于编程的代码,并能够被加载调用。扩展(extension)可以被任意可加载的附加库所引用,但是在Ruby中这通常意味着它们不是用Ruby而是用C语言编写而成的。如果要说正在编写的是Ruby扩展,就意味着已经假定那是用C语言编写的。

要试一下这个例子,需要将程序分写在两个文件中。第一个文件,名为loaddemo.rb,应该包含如下代码:

当它遇到load方法的调用时,Ruby就会加载第二个文件,这个文件名为loadee.rb,包含如下代码:

这两个文件应该放在同一个目录下(假定存在示例代码目录)。在命令行中运行loaddemo.rb,可以看到如下输出结果:

这个结果可以追溯到执行文件的某一行,以及执行的顺序。

为了在loaddemo.rb中加载名为loadee.rb的文件,将它作为参数:

如果将要加载的文件就在工作目录中,Ruby将能够根据名称找到它。如果不是,Ruby将在加载路径(load path)中查找它们。

Ruby解释器的加载路径是一系列目录,请求加载时,Ruby会在这些目录中搜索文件。可以使用$:(美元符号及冒号)检查加载目录下的这些子目录的名称,看到的结果取决于用户所使用的平台。在Mac OS X上,一个典型的加载目录如下(这个示例包含了.rvm的路径,它是Ruby版本管理器所决定的Ruby版本的路径):

在你的电脑中,“ruby-2.1.0”左边的部分可能会有所不同,如“/usr/local/lib/”,但是子目录的基本模式都是一样的。当加载一个文件时,Ruby将会自上而下地在每一个子目录中搜索。

注意


当前的工作目录,通常使用一个点(.)表示,这不会包含在加载目录中。加载命令的作用如前面所介绍,这只是一个特例。

可以在load命令中使用代表上级目录的双点(..)符号导航到相对目录:

注意,如果在程序运行中改变当前的目录,相对目录的引用也将会改变。

注意


记住load是一个方法,在程序文件中,只有Ruby遇到它的时候才会执行。Ruby不会搜索整个文件去执行load命令。也就是说,当Ruby解释器遇到它的时候,它才会去寻找它要加载的文件。这意味着需要加载的文件名可以在运行时动态地决定。甚至可以在条件语句中包含一个load指令的调用,让它只有在条件为true的时候才会被执行。

同时也可以强制指定load搜索一个完全限定的文件路径,而不管加载路径的内容。

当然,这比起使用加载目录或者相对路径来说兼容性会差一些,但是这可能会很有用处,尤其是如果拥有一个字符串变量,其中包含一段绝对路径并想要加载它的时候。

load命令总是会加载所请求的文件,不论这个文件是否已经加载过。假如一个文件在几次加载过程中发生改变,那么最新版本的文件将优先使用并覆盖之前加载的版本。尤其是在irb会话中,当在编辑器中修改一个文件时,想要立刻测试修改的效果,这将非常有用。

另一个加载文件的方法是require,它同样也搜索默认的加载路径中的目录。但是require有一些load不具有的特点。

loadrequire最大的不同在于,require就算调用多次也不会重新加载已经加载过的文件。Ruby会持续追踪已经被请求的那些文件而不会重复加载它们。

require比起load来说更为抽象。严格来说是不能请求一个文件的,而只能请求一个功能。一般来说,做到这一点甚至不用指定文件的扩展名。为了验证之前所述,将loaddemo.rb中的这一行进行修改,从

修改为

当运行loaddemo.rb时,即使提供了需要加载的文件的完整文件名,得到的结果也可能与之前相同。

通过把loadee看作一个“功能”而不是一个文件,require对用Ruby编写的扩展和使用C语言写成的扩展都用一样的方式。另外,.rb扩展名的文件与其他扩展名为.so、.dll或者.bundle的文件使用方式也是一样的。

指定工作目录

require不能辨识出当前的工作目录(.)。用户可以显式地指定它,例如:

或者可以使用数组添加运算符(<<),把当前目录添加到加载路径当中。

这样,就不必在调用require的时候显式地指定工作目录了。

也可以给require指定完全限定的路径,和使用load一样,把文件或者功能加载进来。读者也可以混合使用该规则,例如,即使是将静态路径与路径末端更为抽象的语法功能混合使用,以下语法也是可以正常运行的,例如:

尽管load很有用,尤其是当加载多于一个文件的时候,但是require是一个日常使用的技术,用于请求Ruby扩展和库,不论是标准库还是第三方库。与加载loadee文件相比,请求标准库的功能要简单得多,只使用require就可以请求想要的任何库文件。之后,扩展中新的类和方法都可以使用了。下面的例子中,给出了请求前后在irb会话中的不同。

第一次调用scanf的时候失败并报错❶。但是在调用了require之后❷,没有编程人员的介入,"David Black"这个字符串对象也响应了scanf消息。(在这个例子中❸,使用空格为隐式分隔符,用于把原字符串抽取为两个连续的字符串)

require_relative是第三种加载文件的方式。这个指令会搜索相对于所在文件的目录来加载功能。因此在前一个例子中,可以这样:

这样就可以不用把当前目录加入加载路径中。当需要导航到某个本地目录结构中的时候,require_relative是一个便捷的方式,例如:

接下来将对随Ruby发布的命令行工具进行一次测验,以此总结这一章所学到的知识。

安装Ruby后,就可以得到一组重要的命令行工具,它们被安装在配置信息bindir所指定的文件夹中,通常是/usr/local/bin、/usr/bin或者/opt同等的目录中。(可以使用require "rbconfig"去测试一下RbConfig::CONFIG["bindir"]返回的结果。)这些命令行工具具体是以下几个。

这一节将会讲述除erbtestrb之外的所有工具。它们在特定的条件下都很有用,但是不作为学习Ruby语言首要的目标和基础知识。

在这里读者可以不必记住本节的所有技术点,而是通读之后先留下感性认识。不久之后将会经常(尤其是一些命令行参数和ri实用工具)用到这些内容,随着使用频率的提高,对Ruby语言的理解会逐步加深。

从命令行启动Ruby解释器时,不仅可以提供程序的名称,也可以提供一个或多个命令行开关,正如在本章中所见那样。用户选择的开关将会通知解释器使用不同的特殊行为方式,抑或使用特殊的功能。

Ruby有超过20个命令行开关。其中一些用得很少,而另外一些对于Ruby程序员来说使用频率较高。表1-6概括了最常用的一些Ruby命令行开关。

表1-6 最常用的Ruby命令行开关

开  关

描  述

用  例

-c

不执行程序只检查程序文件的语法

ruby -c c2f.rb

-w

在程序执行过程中给出警告信息

ruby -w c2f.rb

-e

执行在命令行中引号内的代码

ruby -e 'puts "Code demo!"'

-l

行模式:在每一行输出后打印换行

ruby -le 'print "+ newline!"'

-rname

请求指定名字的扩展

ruby –rprofile

-v

显示Ruby版本信息,在详细模式(verbose mode)下执行程序

ruby –v

--version

显示Ruby版本信息

ruby –-version

-h

显示所有解释器开关的信息

ruby –h

接下来仔细看一看每一个开关的使用细节。

1.语法检查(-c

开关-c通知Ruby对一个或者多个文件的语法精确性进行代码检查,但不执行代码。它通常会和-w开关一起使用。

2.开启警告(-w

使用-w开关运行程序,解释器将会进入警告模式(warning mode)。这意味着用户将会看到比预期更多的警告输出,从而提示用户在程序中需要注意的地方,尽管这些不是语法错误,但都有文体上和逻辑上值得斟酌的地方。根据Ruby的设计:“你所编写的程序没有语法错误,但是它很怪异。你确定你所编写的程序吗?”甚至不用添加这个开关,Ruby也会给出确定的警告,只是相对而言要少于完全警告模式。

3.执行字符串脚本(-E

开关-e会通知解释器,命令行中的引号内包含了Ruby的代码,应该去执行这段真实的代码,而不是执行文件中的代码。这样可以很方便地用于快速执行脚本代码,而不用把代码写在文件中再去执行文件。

例如,将自己的名字逆向地打印输出。在下面的例子中,添加执行开关(execute switch)可以快速地使用一条命令行工具实现这个功能:

单引号中包含的内容是一个Ruby程序的整体(虽然很短)。假如想要运行多于一行的程序并使用-e开关,需要在小程序中使用文本换行符(回车):

或者可以使用分号进行行分隔:

注意


为什么在两行的reverse例子中,在程序代码的输出结果的两行之间会有一个空格呢?因为用键盘输入的一行是以一个换行符结束的,所以当反转输入的时候,新字符串就伴随新一行产生了。当请求Ruby操作和打印数据的时候,Ruby是非常遵循文字本身的。

4.行模式运行(-L

开关-l将会产生一个效果:程序的每一次字符串输出都会被它自身的一行所替代,即使通常情况不是这样的。通常情况下,使用print打印输出不会自动以一个换行符结束,它与puts的使用不一样,但是使用了开关-l后,print也会以换行符结束。

下面使用温度转换器的程序作为例子来对比printputs的区别,用以确信程序不会在它们的输出中间插入额外的换行符(见1.1.5节)。可以使用-l开关逆向实现这个效果,这甚至将致使print打印输出的每一行都在它们自己所属的那一行中。下面展示了差别:

在这个例子中,使用-l的结果并不是期望的。但是这个例子展示出了开关的效果。

如果某一行已经存在换行符,使用-l开关会添加另一个换行符。通常-l开关是不常使用的,因为puts的功能已经足够达到按需添加换行符的需求,不过了解-l的用途还是有益的。

5.请求名称文件和扩展(-rname

开关-r用于调用require,并依赖其命令行参数,ruby -rscanf将会在运行开始时加载scanf。可以放置多个-r在单行的命令行参数中。

6.运行在详细模式之下(-v--verbose

使用-v运行程序将会执行两个任务:打印输出当前使用Ruby的版本信息,然后开启与-w开关相同的警告机制。最常使用-v的场景是找出Ruby的版本号:

本例中使用的是Ruby 2.1.0(补丁级别0),于2013年12月25日发布,并基于i686机器编译,运行在Mac OS X系统上。这里因为没有程序需要运行,所以Ruby立刻就打印输出了版本信息。

7.打印Ruby版本信息(--version

这个开关可以让Ruby打印一次版本信息,然后退出。就算指定了程序文件名,也不会执行任何的代码。可以回忆一下-v开关在详细模式下打印版本信息并执行代码的过程。可以说,-v开关是悄悄地完成了打印版本和运行代码的模式,而-- version仅仅输出了版本  信息。

8.打印帮助信息(-h--help

这两个开关(-h--help)将会打印输出一个包含全部可用的命令行开关的列表,并概述它们的功能。

除了可以单独使用这些开关,也可以在Ruby调用的时候合并两个或者多个一起使用。

9.合并使用开关(-cw

之前已经介绍过-cw这样的合并使用方式了,它会检查文件的语法错误而不执行文件,当然也会给出警告:

另一个很常用的合并使用的例子是-v-e,这将显示运行的Ruby的版本,同时运行单引号内的代码内容。有很多关于Ruby合并开关使用的讨论,如邮件列表和其他地方,人们使用它来验证相同的代码在不同版本之间的差异。例如,如果想要清晰地显示一个字符串调用方法start_with?在Ruby 1.8.6中不能运行而在Ruby 2.0中可以,那么可以分别运行这两个版本:

(当然,这要求系统中安装了两个版本)第一次运行(使用1.8.6版本)程序获得了undefined method 'start_with?'消息❶,这意味着执行了一个不存在的操作。但是使用Ruby2.1.0运行相同的代码段时,运行就正常了❷,Ruby打印输出了true。这是一个非常便捷的方式去分享和提出关于Ruby版本切换时的问题。

现在,将讲述前面所提到的交互式Ruby解释器irb,并进一步地了解它。这一部分在本章的一开头已经有过叙述,所以读者可能已经有所了解。如果没有,那么借此机会可以学习一下这个特殊且有用的Ruby工具。

指定开关

可以给Ruby提供分隔式的开关,例如:

或者

但是通常将它们合并在一起使用,正如正文中所讲述的例子。

正如本书中所见,irb是一个交互式的Ruby解释器,这意味着它不用处理文件,而是处理会话中所输入的代码。irb是一个很好的工具,可以用于测试Ruby代码,同时也是一个学习Ruby的好工具。

在命令行中输入irb,就可以开启irb会话,irb将显示以下提示符:

正如之前所述,还可以使用--simple-prompt选项使irb输出更为简单明了:

irb一旦启动,便可以输入Ruby命令。这里可以运行单次摄氏-华氏度转换程序。在本例中,irb就像一个可装入口袋的计算器:它能计算任何输入并打印结果。因此不必使用print或者puts命令:

如果想要知道一年有多少分钟(假如读者手边没有Rent乐队热门金曲的CD),就输入适当的乘法计算表达式:

当然,irb也会处理输入的Ruby指令。比如,将天数、小时数、分钟数赋值给变量,然后将这些变量的值相乘,可以在irb中这样做:

上面就是期望的计算结果。但是看一下上面条目的前3行,当输入days = 365的时候,irb会相应输出365,为什么?

表达式days = 365是一个赋值表达式:将值365赋给了名为days的变量。赋值表达式最重要的任务就是将值赋给变量,因此可以在之后使用该变量。但是赋值表达式(days = 365这一整行)也有一个值,赋值表达式的值就是它右边的值。当irb发现任何表达式时,它就会输出这个表达式的值。因此,当irb发现days = 365时,它就输出365。这看起来有些输出过度,这是因为其处在irb之中,与在irb中输入2+2就看到了结果,而没有显式地使用print语句去打印结果是同样的道理。

同样,调用puts方法也有一个返回值,名为nil。假如在irb中输入一个puts语句,irb将会严格地执行它,同时还会打印输出puts的返回值。

这里有一种方法可以让irb不再喋喋不休,即使用-noecho参数。下面展示它如何使用:

幸好有-noecho,附加的表达式不会回显其结果了。puts命令确实被执行了(可以看到输出"Hi"),但是puts的返回值(nil)被屏蔽了。

中断irb

在irb中可能会卡在一个循环中,或者会话看起来像是失去响应(就好像是输入了左双引号而没有输入右双引号,或者类似的代码行)。重新回到控制的方法取决于系统本身,在最常见的系统中,使用Ctrl+C组合键可以达到这一目的。另一个方法是使用Ctrl+Z组合键。这是用户的系统中直接作用于irb上,最优、最通用的中断信息的方式。当然,如果任务被真的冻结,无响应,可以到进程或者任务管理器工具中终止irb进程。

要从irb中正常退出,输入exit即可。在许多系统中,Ctrl+D组合键同样适用。

偶然情况下,会遇到irb出现问题(那是说遇到致命错误然后结束进程),而大多数时候它会捕获自己的错误,然后让用户继续操作。

一旦掌握了使用irb的窍门并用于打印输出一切的值,以及如何关闭它,就会发现irb是一个极为有用的工具(和玩具)。

Ruby的源代码采用一种能自动生成文档的方式进行标记,然后通过一些工具解析和显示它们,这些工具是ri和RDoc,下面就会讲述到。

最早由Dave Thomas编写的ri(Ruby索引)和RDoc(Ruby文档)是为Ruby程序提供文档的关系很紧密的一对工具。ri是一个命令行工具,而RDoc体系中包含了命令行工具rdocrirdoc是独立的程序,通过命令行来运行。(虽然用户也可以使用Ruby程序内所提供的工具,但这里暂时不讨论这方面的内容。)

RDoc是一个文档系统。假如在程序文件(Ruby或者C)中使用规定的RDoc格式编写了注释,rdoc会扫描程序文件,并抽取这些注释,智能地(通过注释的内容进行索引)组织它们,最后创建出漂亮的格式化文档。在Ruby源码树以及许多Ruby安装目录的Ruby文件中,在许多的源码文件中可以看到RDoc标记,包括了Ruby文件和C语言文件。

ri与RDoc相互配合:它提供了一种方式用于查看RDoc萃取过和组织过的文档信息。具体来说(虽然不是唯一的,除非用户定制它),ri被用于组织和显示从Ruby源文件而来的RDoc的信息。在完全安装好Ruby的任何系统中,都可以使用一个简单的命令行工具ri获得关于Ruby语言的详细信息。

例如,下面是请求关于string对象的upcase方法的信息的方法:

显示如下结果:

Stringupcase中间的散列标记(#),用于在ri命令中表明查找的实例方法,并与类方法区分。要查询类方法,可以使用分隔符::替换#。第3章将会讲述实例方法和类方法的区分。这里的要点是通过命令去处理大量的文档。

注意


默认情况下,运行ri会通过一个分页器(如UNIX中的more命令)输出结果。它会在输出的末端暂停,直到用户点击空格或者其他按键才会展示下一屏的信息,或者当所有的信息显示完毕就会完全退出。准确地说,在这个例子中,用户必须按下的按键因操作系统和分页器不同会有所变化。空格键、回车键、Esc键、Ctrl+C组合键、Ctrl+D组合键和Ctrl+Z组合键都是很好的选择。如果想要使用ri而不进行分页显示,可以在命令行使用的时候加入-T开关(ri –Ttopic)。

下一节将会讲述Ruby命令行工具中的rake

正如其名字所代表的含义(由“Ruby make”而来),rake是一个极具make特性的任务管理实用工具。它是由已故的Jim Weirich编写完成的。同make一样,rake读取和执行定义在一个文件中的任务,这个文件名为Rakefile。和make不同,rake必须使用Ruby语法定义任务。

代码清单1-5显示了一个Rakefile。假如列表中的内容保存到一个称为Rakefile的文件,就能够在命令行中运行它:

rake执行了admin命名空间中的clean_tmp任务。

代码清单1-5 Rakefile在admin命名空间中定义了clean_tmp任务

这里,rake定义任务的时候用到了许多本书中还没出现的Ruby技术,但其基本逻辑是非常简单的。

(1)循环进入/tmp目录下的每一个目录条目❶。

(2)除非当前条目是一个文件,否则跳出当前的循环。提示一下,隐藏文件也不会被删除,因为列出目录的操作不会包括它们❷。

(3)提示删除文件❸。

(4)假如用户输入y(或者任何以y开头的字符串),则删除文件❹。

(5)假如用户输入q,中断循环,任务结束❺。

主要的编程逻辑是这样组成的:通过循环目录列表中的条目(参见“使用each遍历一个集合类型”),然后通过case语句进行条件判断并执行(这些技术将会在第6章中讲述)。

使用each遍历一个集合类型

表达式Dir["/tmp/ *"].each do |f|调用了一个包含目录条目名称的数组的each方法。整个代码块从do开始并在end处结束(endDir使用统一缩进整齐排列),并对每数组中每一项执行一次。每一次执行,当前项都会绑定到参数f,这就是|f|语句的意义。在接下来的章节中,将会看到许多使用each的地方。在第9章讲述迭代器(iterator)的时候,将会对each进行详细的讲述。

上面任务定义中的命令desc提供了对任务描述的方式。这不仅在用户研究文件的时候可以派上用场,还可以用于在特定时间查看rake可以执行的所有任务。假如所处的目录中包含一个代码清单1-5中的Rakefile,便可以使用如下命令:

可以看到所有定义过的任务列表。

对于rake的命名空间和任务名称可以任意命名。甚至可以不需要一个命名空间,可以在顶级命名空间定义一个任务,如下所示:

然后使用简单的名称调用它:

但是,在任务中使用命名空间是个好主意,尤其是在用户定义的任务数量成倍增长的时候。可以定义命名空间至任意的深度,例如,下面的结构是合法的:

定义好的任务是这样调用的:

正如目录清理的例子所示,rake任务不会被限制在与Ruby编程相关的操作中。使用rake,用户可以随意使用Ruby语言以达到编写任何所需任务的目的。

下一个将要讲述的是gem命令,它使得安装第三方Ruby组件包变得非常容易。

RubyGems库和实用工具集合包括了打包、安装Ruby库和应用程序的工具。这里不会覆盖创建gem的内容,只是先看一下gem安装程序和使用的方法。

使用gem安装一个Ruby的程序包通常是很简单的,在gem之后使用简单的install命令即可

这个命令将会输出如下内容(这依赖于已经安装的gem和新安装的gem的依赖包):

这些状态报告之后跟随着许多行信息,它展示了对于已经安装好的不同gem的ri和RDoc文档信息。(文档的安装是通过RDoc与正在处理的gem源文件关联,所以要耐心等待这个过程,它通常是gem安装中最长的过程。)

在gem安装的过程中,gem从rubygem.org(www.rubygems.org)下载所需的gem文件。这些文件都是使用.gem格式,被保存在用户gems目录下的缓存子目录中。当然也可以安装存放在本地磁盘或者其他媒介中的gem文件。指定文件的名称即可安装:

假如指定安装的gem名称没有使用完全文件名(如ruport),gem将会查找当前目录和RubyGems系统中的本地缓存。本地安装仍然会搜索远程的依赖包,除非使用-l(local)作为gem的命令行参数,它严格限制所有的操作都在本地进行。假如想要仅使用远程安装gem并包含依赖包,可以使用-rremote)参数。在大多数情况下,简单地使用“gem install包名”这样的方式即可(要卸载一个gem包,使用“gem uninstall包名”命令)。

一旦安装了一个gem包,就可以通过require方法使用它。

加载和使用gem包

此刻不会看到gem包位于初始化加载路径($:)之中,但仍然可以使用require请求它们。这里列出了怎样请求“hoe”(帮助用户打包自己的gem实用工具)的方式,并确保Hoe gem包已经安装:

在这里,hoe的关联目录将会出现在加载路径中,假如使用grep匹配“hoe”模式打印输出$:的值,如下:

假如为了特殊的库安装了一个库的多个版本的gem,然后想要强制使用其中一个版本而不是最常用的版本,也可以使用gem方法。(注意,这个方法和命令行工具中的gem不是一个工具。)在这个例子中,展示了如何强制使用非当前版本的Hoe:

当然,更多时候都会使用最新gem。只是gem系统给出了可以微调gem使用的工具,这也应该如用户所需。

关于RubyGems就讲述到这里,至此已经学完了bin/目录的知识,接下来将进一步学习Ruby语言的核心部分。

在本章中,看到了许多重要的Ruby语言基础知识,包括:

读者现在拥有了一份关于Ruby工作原理和Ruby编程环境所需工具的蓝图。它包含了之前看到和练习过的重要Ruby技术。接下来,本书准备开始系统地介绍Ruby。

生存工具箱(survival kit)通常是指语言教授者提供给外语初学者的语用套用语。——译者注

这里开关的作用如同Linux系统命令中的选项,如-v显示版本号,-h显示帮助。——译者注

可以在http://ruby-lang.org 找到Ruby最新版本的安装说明。

Rent乐队的热门金曲Seasons of Love的歌词中包含对一年有多少分钟的描述。——译者注


相关图书

“笨办法”学Ruby(第3版)
“笨办法”学Ruby(第3版)
面向对象设计实践指南:Ruby语言描述
面向对象设计实践指南:Ruby语言描述
R和Ruby数据分析之旅
R和Ruby数据分析之旅

相关文章

相关课程