次のようなことができるように、1 以外のステップ サイズを指定するために Range のサブクラスを作成したいと思います。
>> a = RangeWithStepSize.new(-1, 2, 0.5).each {|x| puts(x)}
-1.0
-0.5
0.0
0.5
1.0
1.5
2.0
=> -1..2
実装での私の最初の試みはうまくいきません:
class RangeWithStepSize < Range
attr_reader :step_size
def initialize(start_v, end_v, step_size, exclusive = false)
super(start_v, end_v, exclusive)
@step_size = step_size
end
def each
self.step(step_size).each
end
end
>> a = RangeWithStepSize.new(-1, 2, 0.5).each {|x| puts(x)}
=> #<Enumerator: [-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0]:each>
RangeWithStepSize#each が有効な列挙子を返しているように見えますが、列挙されません。理由はありますか?
<aside>
これは関連している可能性がありますが、ドキュメントで指定されているように、ブロックのない Range#step は列挙子を返さないことに気付きました。代わりに配列を返します。
>> Range.new(-1, 2).step(0.5).class
=> Array
配列は列挙可能ですが、列挙子ではありません。これはドキュメントのバグですか?</aside>
説明
ステップ サイズをカプセル化する Range のバージョンを作成したいので、次のようにします。
a = RangeWithStepSize(-1, 2, 0.5)
b = RangeWithStepSize(-1, 2, 0.25)
...したがって、a を列挙すると 0.5 のステップ サイズが生成され、b は 0.25 が生成されます。