基于my_each枚举器定义my_times枚举器?

时间:2014-08-17 00:30:57

标签: ruby

假设我有自己的each实现:

class Array
  def my_each
    c = 0
    until c == size
      yield(self[c])
      c += 1
    end
    self
  end
end

如何使用my_each自行实现times?这是我的方法:

class Integer
  def my_times
    Array.new(self) { |i| i }.my_each do |el|
      yield el
    end
  end
end

但我不是特别喜欢它,因为我正在创建一个数组。但是,还有其他方法可以实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

你可以这样做:

class Integer
  def my_times
    return (0...self).to_enum unless block_given?
    (0...self).each { |i| yield i }
  end
end

5.my_times { |i| puts i*i }
0
1
4
9
16

5.my_times #=> #<Enumerator: 0...5:each>

我使用过Range#each。要使用Array#my_each,我们必须将范围转换为数组:

[*(0...self)].my_each { |i| yield i }

回想一下,如果没有给出块,Integer#times将返回一个枚举器。 Array#each也是如此;您需要修复my_each才能使其等同于Array#each

但您不需要eachmy_each

class Integer
  def my_times
    return (0...self).to_enum unless block_given?
    i = 0
    while(i < self) do
      yield i
      i += 1
    end
  end
end

5.my_times { |i| puts i*i }
0
1
4
9
16

5.my_times #=> #<Enumerator: 0...5:each>