为什么Ruby中的each迭代器会首先执行?

5

在使用Ruby进行简单任务时,我遇到了一个奇怪的问题。我只想用each方法迭代字母表,但是迭代首先执行:

alfawit = ("a".."z")
puts "That's an alphabet: \n\n #{ alfawit.each { |litera| puts litera } } "

而这段代码将产生以下结果:(缩写)

a
b
c
⋮
x
y
z
That's an alphabet: 

 a..z 

有什么想法,为什么会出现这种情况或者我做错了什么吗?
提前感谢。

你期望的结果是什么? - Stefan
像Ursus一样正确地列出“这是一个字母表”后面的字母顺序。我曾经认为我能够像我做的那样嵌套迭代。 - Michalko
2个回答

5
因为你的each调用被插入到字符串字面量中,在固定字符串之前执行。此外,each返回一个Enumerable,实际上你甚至打印了它。尝试这个。
alfawit = ("a".."z")
puts "That's an alphabet: \n\n"
alfawit.each { |litera| puts litera } 

或者

puts "That's an alphabet: \n\n"
("a".."z").each { |litera| puts litera } 

如果您想要使用插值法,也可以,但是以这种方式:

alfawit = ("a".."z")
puts "That's an alphabet: \n\n#{alfawit.to_a.join("\n")}"

1
谢谢。我曾经苦苦思索了几天,但那其实很简单。 - Michalko
1
我的荣幸,先生 :) - Ursus

3

如果您将插值部分提取到变量中,就可以轻松地了解正在发生的情况:

alfawit = ("a".."z")
foo = alfawit.each { |litera| puts litera }
puts "That's an alphabet: \n\n #{ foo } "

第二行出了问题:each会对范围内的每个元素调用块,然后返回接收者,导致foo变成alfawit
以下是另一种获得所需结果的方法:
alfawit = "a".."z"
puts "That's an alphabet:", alfawit.to_a

puts 命令会将每个参数输出到一个新行,但对于数组参数,它会将每个 元素 输出到一个新行。结果如下:

That's an alphabet:
a
b
c
⋮
x
y
z

同样地,你可以通过使用 * 将范围转换为一个参数列表
alfawit = "a".."z"
puts "That's an alphabet:", *alfawit

这相当于:

puts "That's an alphabet:", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接