2

次のようなことができるように、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 が生成されます。

4

1 に答える 1

2

あなたはこれができることを知っていますよね?ここでは継承は必要ありません。

(-1..2).step(0.5) do |x|
    puts x
end

あなたのコードは、いくつかの小さな調整で動作します:

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 (&block)
    self.step(step_size).each(&block)
  end

end
于 2011-09-28T17:54:34.020 に答える