本节书摘来自异步社区《ruby程序员修炼之道》一书中的第1章,第1.4节易用的ruby工具和应用程序,作者【美】david a. black(戴维 a. 布莱克),更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.4 易用的ruby工具和应用程序
安装ruby后,就可以得到一组重要的命令行工具,它们被安装在配置信息bindir所指定的文件夹中,通常是/usr/local/bin、/usr/bin或者/opt同等的目录中。(可以使用require "rbconfig"去测试一下rbconfig::config["bindir"]返回的结果。)这些命令行工具具体是以下几个。
ruby:解释器。
irb:ruby交互式解释器。
rdoc和ri:ruby文档工具。
rake:ruby的make工具,一套任务管理实用工具。
gem:一套ruby库和应用程序包管理实用工具。
erb:一套模版系统。
testrb:一个用于测试框架的高级工具。
这一节将会讲述除erb和testrb之外的所有工具。它们在特定的条件下都很有用,但是不作为学习ruby语言首要的目标和基础知识。
在这里读者可以不必记住本节的所有技术点,而是通读之后先留下感性认识。不久之后将会经常(尤其是一些命令行参数和ri实用工具)用到这些内容,随着使用频率的提高,对ruby语言的理解会逐步加深。
1.4.1 解释器的命令行开关
从命令行启动ruby解释器时,不仅可以提供程序的名称,也可以提供一个或多个命令行开关,正如在本章中所见那样。用户选择的开关将会通知解释器使用不同的特殊行为方式,抑或使用特殊的功能。
ruby有超过20个命令行开关。其中一些用得很少,而另外一些对于ruby程序员来说使用频率较高。表1-6概括了最常用的一些ruby命令行开关。

接下来仔细看一看每一个开关的使用细节。
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也会以换行符结束。
下面使用温度转换器的程序作为例子来对比print和puts的区别,用以确信程序不会在它们的输出中间插入额外的换行符(见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提供分隔式的开关,例如:
或者
但是通常将它们合并在一起使用,正如正文中所讲述的例子。
1.4.2 走近ruby的交互式解释器irb
正如本书中所见,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,下面就会讲述到。
1.4.3 ri和rdoc
最早由dave thomas编写的ri(ruby索引)和rdoc(ruby文档)是为ruby程序提供文档的关系很紧密的一对工具。ri是一个命令行工具,而rdoc体系中包含了命令行工具rdoc。ri和rdoc是独立的程序,通过命令行来运行。(虽然用户也可以使用ruby程序内所提供的工具,但这里暂时不讨论这方面的内容。)
rdoc是一个文档系统。假如在程序文件(ruby或者c)中使用规定的rdoc格式编写了注释,rdoc会扫描程序文件,并抽取这些注释,智能地(通过注释的内容进行索引)组织它们,最后创建出漂亮的格式化文档。在ruby源码树以及许多ruby安装目录的ruby文件中,在许多的源码文件中可以看到rdoc标记,包括了ruby文件和c语言文件。
ri与rdoc相互配合:它提供了一种方式用于查看rdoc萃取过和组织过的文档信息。具体来说(虽然不是唯一的,除非用户定制它),ri被用于组织和显示从ruby源文件而来的rdoc的信息。在完全安装好ruby的任何系统中,都可以使用一个简单的命令行工具ri获得关于ruby语言的详细信息。
例如,下面是请求关于string对象的upcase方法的信息的方法:
显示如下结果:
在string和upcase中间的散列标记(#),用于在ri命令中表明查找的实例方法,并与类方法区分。要查询类方法,可以使用分隔符::替换#。第3章将会讲述实例方法和类方法的区分。这里的要点是通过命令去处理大量的文档。
默认情况下,运行ri会通过一个分页器(如unix中的more命令)输出结果。它会在输出的末端暂停,直到用户点击空格或者其他按键才会展示下一屏的信息,或者当所有的信息显示完毕就会完全退出。准确地说,在这个例子中,用户必须按下的按键因操作系统和分页器不同会有所变化。空格键、回车键、esc键、ctrl+c组合键、ctrl+d组合键和ctrl+z组合键都是很好的选择。如果想要使用ri而不进行分页显示,可以在命令行使用的时候加入-t开关(ri –ttopic)。**
下一节将会讲述ruby命令行工具中的rake。
1.4.4 任务管理实用工具:rake
正如其名字所代表的含义(由“ruby make”而来),rake是一个极具make特性的任务管理实用工具。它是由已故的jim weirich编写完成的。同make一样,rake读取和执行定义在一个文件中的任务,这个文件名为rakefile。和make不同,rake必须使用ruby语法定义任务。
代码清单1-5显示了一个rakefile。假如列表中的内容保存到一个称为rakefile的文件,就能够在命令行中运行它:
这里,rake定义任务的时候用到了许多本书中还没出现的ruby技术,但其基本逻辑是非常简单的。
(1)循环进入/tmp目录下的每一个目录条目。
(2)除非当前条目是一个文件,否则跳出当前的循环。提示一下,隐藏文件也不会被删除,因为列出目录的操作不会包括它们。
(3)提示删除文件。
(4)假如用户输入y(或者任何以y开头的字符串),则删除文件。
(5)假如用户输入q,中断循环,任务结束。
主要的编程逻辑是这样组成的:通过循环目录列表中的条目(参见“使用each遍历一个集合类型”),然后通过case语句进行条件判断并执行(这些技术将会在第6章中讲述)。
使用each遍历一个集合类型
表达式dir["/tmp/*"].each do |f|调用了一个包含目录条目名称的数组的each方法。整个代码块从do开始并在end处结束(end与dir使用统一缩进整齐排列),并对每数组中每一项执行一次。每一次执行,当前项都会绑定到参数f,这就是|f|语句的意义。在接下来的章节中,将会看到许多使用each的地方。在第9章讲述迭代器(iterator)的时候,将会对each进行详细的讲述。
上面任务定义中的命令desc提供了对任务描述的方式。这不仅在用户研究文件的时候可以派上用场,还可以用于在特定时间查看rake可以执行的所有任务。假如所处的目录中包含一个代码清单1-5中的rakefile,便可以使用如下命令:
可以看到所有定义过的任务列表。
对于rake的命名空间和任务名称可以任意命名。甚至可以不需要一个命名空间,可以在顶级命名空间定义一个任务,如下所示:
但是,在任务中使用命名空间是个好主意,尤其是在用户定义的任务数量成倍增长的时候。可以定义命名空间至任意的深度,例如,下面的结构是合法的:
定义好的任务是这样调用的:
正如目录清理的例子所示,rake任务不会被限制在与ruby编程相关的操作中。使用rake,用户可以随意使用ruby语言以达到编写任何所需任务的目的。
下一个将要讲述的是gem命令,它使得安装第三方ruby组件包变得非常容易。
本节书摘来自异步社区《ruby程序员修炼之道》一书中的第1章,第1.4节使用gem命令安装组件包,作者【美】david a. black(戴维 a. 布莱克),更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.4.5 使用gem命令安装组件包
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并包含依赖包,可以使用-r(remote)参数。在大多数情况下,简单地使用“gem install包名”这样的方式即可(要卸载一个gem包,使用“gem uninstall包名”命令)。
一旦安装了一个gem包,就可以通过require方法使用它。
加载和使用gem包
此刻不会看到gem包位于初始化加载路径($:)之中,但仍然可以使用require请求它们。这里列出了怎样请求“hoe”(帮助用户打包自己的gem实用工具)的方式,并确保hoe gem包已经安装:
在这里,hoe的关联目录将会出现在加载路径中,假如使用grep匹配“hoe”模式打印输出$:的值,如下:
假如为了特殊的库安装了一个库的多个版本的gem,然后想要强制使用其中一个版本而不是最常用的版本,也可以使用gem方法。(注意,这个方法和命令行工具中的gem不是一个工具。)在这个例子中,展示了如何强制使用非当前版本的hoe:
e:00在线编撰系统图书830种以外的电子书4050329.png
当然,更多时候都会使用最新gem。只是gem系统给出了可以微调gem使用的工具,这也应该如用户所需。
关于rubygems就讲述到这里,至此已经学完了bin/目录的知识,接下来将进一步学习ruby语言的核心部分。