命令行参数
“从命令行开始”。不管Ruby用在哪个系统上,无论是超级的科学工作站或者是嵌入式PDA设备,你无论如何都要从Ruby的解释器开始,这会给我们传递命令行参数的机会。
Ruby的命令行由三个部分组成:Ruby解释器选项,可选的要运行程序的名字,和可选的用于那个程序的一组参数。
ruby [ options ] [ -- ] [ programfile ] [ arguments ]
Ruby选项是命令行直接跟在第一个单词后面的,它不能用连字号,或特殊标志--(两个连字号)开头。
如果命令行上未出现文件名,或如果文件名是单个连字号(-),Ruby从标准输入中读取程序源代码。
传递给程序本身的参数跟随在程序名字的后面。例如:
% ruby -w - "Hello World"
打开警告,从标准输入读取程序,并传递双引号字符串"Hello World"做为参数。
命令行选项
-0[octal] 0标志(数字零)指定记录的分隔字符(,如果没有数字跟随)。-00指出段落模式:记录由两个连续的缺省记录分隔字符分隔。-0777一次读入整个文件(它像个非法字符)。设置$/。
-a 当使用-n或-p时的自动分离模式,等价于在每个循环迭代器上执行$F = $_.split。
-C directory 在运行之前修改工作路径。
-c 只检查符号,不运行程序。
-copyright 打印版权信息并退出。
-d, -debug 设置 $DEBUG 和 $VERBOSE 为 true。这可以用于你的程序的额外追踪。
-e 'command' 执行做为一行Ruby源码的命令。允许几个-e,在同一程序中命令被视做多行。当-e出现时,如果程序文件被忽略,在-e命令被运行完后中止运行。程序运行时使用-e可访问旧的条件中的范围和正则表达式的行为-整数范围比较当前输入行号,正式表达式匹配$_。
-F pattern 指定用于split()的缺省输入字段分隔符($;)(影响-a选项)。
-h, -help 显示一个简短的帮助屏幕。
-I directories 指定预定义的$LOAD_PATH($:)指令。可以有多个-I选项。每个-I后可有多个用冒号:分隔的指令。在类Unix系统上是分号(;)。
-i[extension] 以替换形式编辑ARGV文件。ARGV内的每个文件名,你写入到标准输出的任何东西,都将被回储到那个文件的内容中。如果有扩展名的话,备份文件会被保留下来。
% ruby -pi. bak –e "gsub(/Perl/, 'Ruby')" *.txt
-K kcode 指定要使用的编码。当Ruby使用日语时这个选项很有用。Kcode可以是这些当中的一个: e, E for EUC; s, S 对应 SJIS; u, U 对应 UTF-8; or a, A, n, N 对应 ASCII.
-l 自动进行行尾处理;设置$的值为$/,并且对读入的行自动地进行String#chop!处理。
-n Assumes a while gets; ...; end loop around your program. For example, a simple grep command could be implemented as
% ruby –n –e "print if /wombat/" *.txt
-p Places your program code within the loop while gets; ...; print; end.
% ruby –p –e "$_.downcase!" *.txt
-r library 在运行前请求给出名字的库。
-S 查看程序文件是否使用了RUBYPATH或PATH环境变量。
-s Any command-line switches found after the program filename, but before any filename arguments or before a , are removed from ARGV and set to a global variable named for the switch. In the following example, the effect of this would be to set the variable $opt to "electric".
% ruby -s prog -opt= electric ./mydata
-T[level] 设置安全级别,执行不纯度测试(见379页)。设置$SAFE。
-v, -verbose 设置$VERBOSE为true,打开冗长模式。也打印版本号。在冗长模式中,可打印编译警告。如果命令行上没有指定文件名,则Ruby退出。
--version 显示Ruby的版本信息并退出。
-w 打开冗长模式。与-v不同,如果命令行上没有指定文件名则从标准输入读入程序。我们推荐带 –w 来运行你程序。
-W level 设置警告的级别。可有一个或两个级别(或者没指定级别),等价于-w—给出额外的警告。如果级别为1,运行在标准(缺省)警告级别上。使用-W0则不显示警告(包括使用Kernel.warn的警告)。
-X directory 在运行前更改工作目录。类似于-c directory 。
-x [directory] 从#!Ruby行取出文本,如果指定目录的话,并且要修改工作目录。
-y, -yydebug 在解析器中打开yacc调试器。
ARGV
程序名字后面的任何命令行参数都会对你的程序打开全局数组ARGV。例如,假设test.rb包含了下面程序:
ARGV.each {|arg| p arg }
用下同命令行调用它:
% ruby –w test.rb "Hello World" a1 1.6180
会产生如下输出:
"Hello World"
"a1"
"1.6180"
这是给C程序员准备的—ARGV[0]是传递给程序的第一个参数,不是程序的名字。当前程序的名字是全局变量$0中的变量。注意ARGV的所有值都是字符串。
如果你的程序试图从标准输入来读(或使用特殊文件ARGF,它 321页描述),ARGV内的程序参数将接受文件名,并且Ruby会从这些文件中读入。如果你程序带有混合参数和文件名,确信你在从文件读之前倾空了ARGV数组。
程序中止
方法Kernel#exit中止你的程序,并向操作系统返回一个状态值。虽然,不像一些语言,exit不立即中止程序。Kernel#exit首先引发一个SystemExit异常,你可以捕获它,然后程序执行一系列清除动作,包括运行所有的注册的at_exit方法和对象的finalizer。参考500页的Kernel#exit描述。
环境变量
你可以使用预定义的变量ENV来访问操作系统环境变量。它像哈希表一样响应一些方法。[ENV其实不是哈希表,但如果你需要的话,你可以使用ENV#to_hash,来把它转换到成哈希表]。
ENV['SHELL'] => "/bin/sh"
ENV['HOME'] => "/Users/dave"
ENV['USER'] => "dave"
ENV.keys.size => 34
ENV.keys[0, 7] => ["MANPATH", "TERM_PROGRAM", "TERM", "SHELL",
"SAVEHIST", "HISTSIZE", "MAKEFLAGS"]
当Ruby首次启动时要读取一些环境变量值。这些变量修改解释程序的行为,像表14.1中显示的。
Table 14.1. Ruby使用的环境变量
变量名称
描述
DLN_LIBRARY_PATH
用于搜索被动态加载的模块的路径。
HOME
指向用户的主目录。
LOGDIR
Fallback pointer to the user’s home directory if $HOME is not set. Used only by Dir.chdir.
OPENSSL_CONF
指定OpenSSL的本地配置文件。
RUBYLIB
为Ruby程序添加搜索路径($SAFE 必须被设置成)。
RUBYLIB_PREFIX (Windows only)
Mangle the RUBYLIB search path by adding this prefix to each component.
RUBYOPT
给Ruby添加命令行选项,在命令行选项并解析后进行检查($SAFE 必须设置成0)。
RUBYPATH
指定–S选项,Ruby会搜索路径(缺省值是PATH)。
RUBYSHELL
Shell to use when spawning a process under Windows; if not set, will also check SHELL or COMSPEC.
RUBY_TCL_DLL
Override default name for TCL shared library or DLL.
RUBY_TK_DLL
Override default name for Tk shared library or DLL. Both this and RUBY_TCL_DLL must be set for either to be used.
写入环境变量
Ruby程序可以对ENV对象进行写操作。在大多数系统上这会修改相应的环境变量的值。虽然,这种修改是本地的,只针对于这个进程或其随后的子进程。环境变量的种继承在下面例子中说明。一个子进程若修改了一个环境变量,这个修改会被一个进程继承然后启动。尽管修改对原有的父进程不可见。(这只是证明了它的父进程并不真的知道子进程再做什么。)
puts "In parent, term = #{ENV['TERM']}"
fork do
puts "Start of child 1, term = #{ENV['TERM']}"
ENV['TERM'] = "ansi"
fork do
puts "Start of child 2, term = #{ENV['TERM']}"
end
Process.wait
puts "End of child 1, term = #{ENV['TERM']}"
end
Process.wait
puts "Back in parent, term = #{ENV['TERM']}"
produces:
In parent, term = xtermcolor
Start of child 1, term = xtermcolor
Start of child 2, term = ansi
End of child 1, term = ansi
Back in parent, term = xtermcolor
Ruby在哪里找到它的模块
你使用require或load来使库模块添加到你的Ruby程序内。这些模块中一些应用于Ruby,一些你可以安装Ruby的应用程序文档(RAA),一些是你自己写。Ruby是如何找到它们呢?
当Ruby构建你的特殊机器时,它会预先确定持有库资料的标准目录。这些依赖于机器。你可以像这样在命令行中确定它们
% ruby –e 'puts $:'
在典型的Linux box 上,你或许会找到一些如下面显示的。注意Ruby1.8中,这些目录的次序已被修改—下面目录依赖于它们的机器。
/usr/local/lib/ruby/site_ruby/1.8
/usr/local/lib/ruby/site_ruby/1.8/i686linux
/usr/local/lib/ruby/site_ruby
/usr/local/lib/ruby/1.8
/usr/local/lib/ruby/1.8/i686linux
site_ruby目录持有模块和你添加扩展的模块。依赖于系统的目录(本例中是i686-linux)持有可运行的和其它指定给此机器的。所有这些目录被自动地包含在Ruby对模块的搜索路径内。