1. 第三章
字符串和区间
到目前为止,我已经在我的程序中大量使用了字符串。实际上,在这本书中最早的程序中就
使用到了字符串。就是这段代码:
puts 'hello world'
在我的第一个程序中我使用单引号将字符串引起来,在我的第二个程序中我以另外一种方式,
那就是双引号将字符串引起来:
print('Enter your name: ' )
name = gets()
puts( "Hello #{name}" )
1strings.rb
双引号能做的事情比单引号要多。特别是它们能在代码段中进行赋值,即使都是在引号内的
代码。为了能对变量赋值,你需要使用花括号将变量括起来并在前面加#字符。
在上面的例子里,#{name}在一个双引号字符串中,它将告诉 Ruby 取得 name 变量的值并
将它的值插入该字符串。如果 name 等于”Fred”,那么将打印出”Hello Fred”。
1Strings.rb 示范程序还提供了一些其他的关于双引号字符串内嵌赋值的示例。
一个双引号字符串不仅仅能给像 ob.name 这样的属性或者变量赋值,还能在双引号字符串
中添加表达式如 2*3 和一些代码段如 ob.ten(ten 是一个方法名),以及转义字符如
”n”和”t”分别表示换行和制表符。
一个单引号字符串不能做这样的赋值。然而单引号字符串中可以使用反斜杠来指明下一个字
符按字面意义进行取值。当一个单引号字符串中包含了单引号的时候,这个特性还是有用的,
如下:
'It's my party'
假设 ten 方法返回值为 10,你可以像下面这样写代码:
puts( "Here's a tabta new linena calculation #{2*3} and a method-call
#{ob.ten}" )
由于这是一个双引号字符串,内嵌元素都会进行赋值,打印结果如下:
Here's a tab a new line
2. a calculation 6 and a method-call 10
现在,让我们来看看当使用单引号字符串的时候会发生什么:
puts( 'Here's a tabta new linena calculation #{2*3} and a method-call
#{ob.ten}' )
这次,没有内嵌赋值,它的打印如下:
Here's a tabta new linena calculation #{2*3} and a method- call #{ob.ten}
用户自定义字符分隔符(界定符)
如果出于某种原因,单引号和双引号字符串都不是很方便你使用的话,例如,你的字符串包
含了他多的引号,然而你又不想在每个引号前加反斜杠,你也可以通过其他很多方法来分隔
你的字符串。
2strings.rb
标准的可代替双引号作为字符串界定符的是%Q 和/或者%/和/,而/q 和/可替代单引号。因
此可以这么写:
%Q/This is the same as a double-quoted string./
%/This is also the same as a double-quoted string./
%q/And this is the same as a single-quoted string/
你甚至可以定义你自己的字符界定符。当然其必须是非字母数字的字符,可以包含非打印字
符如换行符,或者其他很多通常在 Ruby 中有特殊意义的字符,如哈希符(#)。你选择的字符
应该跟随在%q 或者%Q 后面,同时你还得保证使用相同的字符来结束字符串。如果你的界
定符是一个开放的括号,那么你必须在字符串的末尾使用相对应的关闭括号进行界定,如下:
%Q[This is a string] 3strings.rb
在 3strings.rb 程序中,你将发现大量的用户精选的字符串界定符的示例。无需多说,在很
多时候使用一些隐秘的字符,如换行符,星号等来进行字符串的界定是很有用的,但是在很
多情况下,实际使用中由此引发的的弊(不仅仅是精神上的痛苦和混乱)总是大于利的。
反引号
另一种字符值得引起特殊的重视,那就是由反引号引起来的字符串,这个引号键在我们键盘
的左手上方的角落里,是一个常被我们所忽视的键。
在使用 print 或者 puts 方法时,Ruby 将这些由反引号引起来的字符串当成是系统可执行的
8. b = (-10..-1)
c = (-10..10)
d = ('a'..'z')
你也可以使用三点代替两点来声明区间:这将会使得区间忽略最后一个值
d = ('a'..'z') #该区间由'a'到'z'
e = ('a'...'z') #该区间由'a'到'y'
你可以使用一个由区间定义的值通过 to_a 方法来创建一个数组,如下:
(1..10).to_a
请注意,to_a 方法并没有针对浮点数进行重载,因为我们知道两个浮点数之间的区间是不
确定的无限的。
str_range.rb
你甚至可以创建一个字符串的区间,但是你需要注意的是你这么做会导致区间比你预想的要
大很多很多。例如,你能想象出下面的声明中变量 str_range 的值是什么吗
str_range = ('abc'..'def')
乍看,从'adc'到'def'的区间看上去一点都不大。但事实上,该语句定义了一个超过 2110 个
值的区间。它们是这么排列的:'abc','abd','abe'知道以'a'开头的组合的末尾,然后从'b'开
始,'baa','bab','bac'等等。不过可以肯定的说,这种使用需求极其少,在使用的时候一定
要万分小心,最好是不要用它。
区间的迭代
你可以使用区间来迭代,其范围为区间的起始值到终止值。比如,这里是一个用来打印从 1
到 10 之间所有整数的例子:
for_to.rb
for i in(1..10) do
puts(i)
end
文本声明符(HEREDOCS)
虽然你可以在单引号和双引号之间写入很长并跨行书写的字符串,但是很多的 Ruby 程序员
更倾向于使用一种名为”heredoc”的方式来替代这种书写方式。一个 heredoc 就是一个
9. 以某个指定的终止标志开始的字符串,这个标志你可以简单地定义。这里,我指定 EODOC
为其终止标志:
heredoc.rb
hdoc1 = <<EODOC
该语句会告诉 Ruby,该语句行后面的是一个字符串,在出现终止符处中止。该字符串将被
赋值给变量 hdoc1。这里有一个完整的 heredoc 赋值的示例:
hdoc1 = <<EODOC
I wandered lonely as a #{"cloud".upcase},
That floats on high o'er vale and hill...
EODOC
默认情况下,heredocs 跟双引号字符串一般,像#{“cloud”.upcase}这样的表达式是会被
计算赋值的。如果你想一个 heredoc 像单引号字符串一般,你可以在指定终止符的时候使
用单引号将终止符括起来:
hdoc2 = <<'EODOC'
I wandered lonely as a #{"cloud".upcase},
That floats on high o'er vale and hill...
EODOC
一个 heredoc 的终止符在默认情况下必须左对齐。如果你想使用缩进的话,你需要在声明
终止符的时候使用<<-而不是<<:
hdoc3 = <<-EODOC
I wandered lonely as a #{"cloud".upcase},
That floats on high o'er vale and hill...
EODOC
这主要取决于是选择一个合适的终止符。甚至连使用一个保留关键字都是合法的(即使这是
非常的不明智的):
hdoc4 = <<def
I wandered lonely as a #{"cloud".upcase},
That floats on high o'er vale and hill...