ruby - 为什么 3.times 需要一个 .each 如果作为参数传递,而不是直接使用,如 "3.times do xyz end"

标签 ruby enumeration enumerable enumerator

这是简单的版本,可以按预期工作

[15] pry(main)> def iter
[15] pry(main)*   3.times do
[15] pry(main)*     puts "Hello"
[15] pry(main)*   end  
[15] pry(main)* end  
=> nil
[16] pry(main)> iter
Hello
Hello
Hello
=> 3

但是当我将 Enumerator 作为参数传递时,它需要一个 .each:

作品:

[17] pry(main)> def iter(enumerator)
[17] pry(main)*   enumerator.each do        # <-------- Here  
[17] pry(main)*     puts "Hello"
[17] pry(main)*   end  
[17] pry(main)* end  
=> nil
[18] pry(main)> iter(3.times)
Hello
Hello
Hello
=> 3

不起作用:

[13] pry(main)> def iter(enumerator)
[13] pry(main)*   enumerator do         # <-------- Here
[13] pry(main)*     puts "Hello"
[13] pry(main)*   end  
[13] pry(main)* end  
=> nil
[14] pry(main)> iter(3.times)
NoMethodError: undefined method `enumerator' for main:Object
from (pry):8:in `iter'

我可能是错的,但看起来 Ruby 正在对“3.times”(即语法糖)给予一些特殊处理。是这种情况,还是我错了,可以从第一原则中预期/推断出这种行为?

顺便说一句,这也有效,这让我怀疑它只是语法糖。

[19] pry(main)> def iter
[19] pry(main)*   3.times.each do
[19] pry(main)*     puts "Hello"
[19] pry(main)*   end  
[19] pry(main)* end  
=> nil
[20] pry(main)> iter
Hello
Hello
Hello
=> 3
[21] pry(main)> 

最佳答案

3.times 被调用,该调用的结果(而不是可调用函数)被传递给 iter 函数。如果 times 在没有 block 的情况下被调用,它会返回迭代器。迭代器本身不占用 block ,但您可以对其调用 each

关于ruby - 为什么 3.times 需要一个 .each 如果作为参数传递,而不是直接使用,如 "3.times do xyz end",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29163369/

相关文章:

ruby-on-rails - 有没有办法设置一个假的电子邮件收件箱来检查电子邮件是否在 ruby​​ on rails 中发送?

ruby - Sinatra 的良好表单助手?

enumeration - Elixir - 循环并添加到 map

Ruby Lazy Enumerable flat_map 不是很懒

ruby - Array#each 与 Array#map

ruby-on-rails - 10001 尝试使用 Activemerchant 从 PayPal 获取授权时出现内部错误

ruby - 如何检查数组的值是否包含一个或多个值?

java - 枚举 hasMoreElements() 返回 false

c - 如何从 C 中的枚举中获取相对字符串值?

javascript - 为什么可枚举: false not cascade to inherited classes in TypeScript?