深入探索
范围
在 Ruby 中,Range 是一个表示指定的起始和终止值之间一组数的类。通常,使用整数定义范围,但也可以使用其它有序值(比如浮点数或字符)来定义范围。值可以是负的,尽管如此,你应该注意起始值应该始终小于终止值。这有一些示例:
a = (1..10)
b = (-10..-1)
c = (-10..10)
d = ('a'..'z')
你也可以使用三个点而不是两个点指定范围:这将创建一个不包含终止值范围:
d = ('a'..'z') # this two-dot range = 'a'..'z'
e = ('a'...'z') # this three-dot range = 'a'..'y'
你可以使用 to_a
方法创建一个由范围定义的数的数组:
(1..10).to_a
请注意,由于两个浮点数之间的数不是有限的,所以 to_a
方法并没有为浮点数所定义。
你甚至可以创建字符串范围,你需要非常的小心,这样做的话最终可能会超出你的预想。例如,看看你是否知道这个范围指定的值:
str_range = ('abc'..'def')
一眼看去,从”abc”到”def”这个范围的值可能不多。实际上,这个范围之间的值不少于 2110 个!它们具体如下:”abc”、”abd”、”abe”等等,直到”a”结束;然后再从”b”开始,”baa”、”bab”、”bac”等等。准确的说,这种范围是不常用的,最好要非常小心或者直接不使用。
范围迭代器
你可以使用范围从起始值迭代到终止值。例如,以下是将数字从1到10打印出来的方法:
for i in (1..10) do
puts( i )
end
HereDocs
虽然你可以在单双引号之间写跨行的长字符串,但许多 Ruby 程序员更喜欢使用名为”heredoc”这种替代类型的字符串。hererdoc 是一个以特定结束标记开始的文本块,这可以是你自己选择的结束标记。这里,我选择了 EODOC 作为结束标记:
hdoc1 = <<EODOC
这告诉 Ruby,直到遇到结束标记时所有行都是单个字符串。这个字符串被赋值给 hdoc1
变量。这是一个完整的例子:
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...
def
一个被赋值为 heredoc 的变量也可以像其它字符串变量一样使用:
puts(hdoc1)
字符串字面量
如本章前面所述,你可以选择使用 %q/ 和 / 来分割单引号字符串,以及使用 %Q/ 和 / 来分割双引号字符串。
Ruby 提供了类似的方法来定义反引号字符串、正则表达式(regular expressions)、符号(symbols)和数组(arrays)的分隔符。以这种方式定义字符串数组特别的有用,这样避免了为每个元素都要输入字符串分隔符。这里是一些字符串字面量分隔符的参考:
%q/ /
%Q/ /
%/ /
%w/ /
%W/ /
%r| |
%s/ /
%x/ /
请注意,你可以选择要使用的分隔符。我选择了 /,而正则表达式则使用了 |(因为 / 是一个常规的正则表达式分隔符),同样地我也可以使用方括号、星号、& 或者其它符号(例如 %W*dog cat#{1 + 2}*
或 %s&dog&
)。这是一些示例:
p %q/dog cat #{1+2}/ #=> "dog cat \#{1+2}"
p %Q/dog cat #{1+2}/ #=> "dog cat 3"
p %/dog cat #{1+2}/ #=> "dog cat 3"
p %w/dog cat #{1+2}/ #=> ["dog", "cat", "\#{1+2}"]
p %W/dog cat #{1+2}/ #=> ["dog", "cat", "3"]
p %r|^[a-z]*$| #=> /^[a-z]*$/
p %s/dog/ #=> :dog
p %x/vol/ #=> " Volume in drive C is OS [etc...]"