为什么 Ruby 每个迭代器先执行?

Why the Ruby each iterator goes first in the execution?

我在 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 

知道为什么它会这样工作或者我做错了什么吗?

提前致谢。

因为您的 each 调用被插入到在固定字符串之前执行的字符串文字中。此外,each returns 和 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")}"

如果将插值部分提取到变量中,您可以很容易地看到发生了什么:

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

第二行引起了麻烦:each 为范围的每个元素调用块,然后 returns 接收方,因此 foo 变为 alfawit .

这是获得所需结果的另一种方法:

alfawit = "a".."z"
puts "That's an alphabet:", alfawit.to_a

puts 在新行输出每个参数,但对于数组参数,它在新行输出每个 元素 。结果:

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

同样,您可以通过 *:

将范围变成 argument list
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"