Enumerable#lazy
依赖于您提供的可枚举#each
方法。如果您的可枚举没有#each
您不能使用的方法#lazy
。现在Kernel#enum_for
并#to_enum
提供指定除以下以外的枚举方法的灵活性#each
:
Kernel#enum_for(method = :each, *args)
但是#enum_for
和朋友们总是构造普通(非惰性)枚举器,从不Enumerator::Lazy
。
我看到Enumerator
在 Ruby 1.9.3 中提供了这种类似的#new 形式:
Enumerator#new(obj, method = :each, *args)
不幸的是,该构造函数在 Ruby 2.0 中已被完全删除。此外,我认为它根本不可用Enumerator::Lazy
。所以在我看来,如果我有一个带有方法的类,我想为其返回一个惰性枚举器,如果该类没有,#each
那么我必须定义一些确实定义的帮助器类#each
。
例如,我有一Calendar
堂课。对我来说,从一开始就列举每个日期是没有意义的。一个#each
是没用的。相反,我提供了一种从开始日期(懒惰地)枚举的方法:
class Calendar
...
def each_from(first)
if block_given?
loop do
yield first if include?(first)
first += step
end
else
EachFrom.new(self, first).lazy
end
end
end
那个EachFrom
类看起来像这样:
class EachFrom
include Enumerable
def initialize(cal, first)
@cal = cal
@first = first
end
def each
@cal.each_from(@first) do |yielder, *vals|
yield yielder, *vals
end
end
end
它有效,但感觉很重。也许我应该继承Enumerator::Lazy
并定义一个构造函数,就像不推荐使用的构造函数一样Enumerator
。你怎么看?