1b491994d6011d720e332af6e1ffd03b

I'm afraid I'm still thinking in "C" terms... :|

class IterableContainer

  CONT = ['a','b','c','d'],[1,2,3,4],['x','y','z']
  # or CONT = ['a','b','c','d']
  @i = 0

  def self.get_next
    result = CONT[@i]
    @i += 1
    if @i > CONT.length
      @i = 1
      return CONT[0]
    end

    return result
  end

  def self.has_next?
    return @i != CONT.length
  end

end

Refactorings

No refactoring yet !

D41d8cd98f00b204e9800998ecf8427e

lordzoner.myopenid.com

August 6, 2009, August 06, 2009 17:59, permalink

1 rating. Login to rate!

Iteration in Ruby is much different than in Java or C.

class IterableContainer
  def initialize
    @contents = ['a','b','c','d']
  end

  def each
    for i in 0..@contents.length
      yield @contents[i]
    end
  end
end

# Then you could call:
ic = IterableContainer.new
ic.each {|o| puts o }

# Which would print:
# 1
# 2
# 3
# 4
D41d8cd98f00b204e9800998ecf8427e

lordzoner.myopenid.com

August 6, 2009, August 06, 2009 18:01, permalink

No rating. Login to rate!

I meant "a b c d", but you get it.

F1e3ab214a976a39cfd713bc93deb10f

Tj Holowaychuk

August 6, 2009, August 06, 2009 19:43, permalink

No rating. Login to rate!
1.upto(4) { |n| p n }
F4192eeb4b26e96deab8b5c68926105d

Muke Tever

August 7, 2009, August 07, 2009 05:52, permalink

No rating. Login to rate!

It seems kind of like reinventing the wheel, anyway.

P.S. I love the 'edit' button a bit too much.

# It looks like you're trying to set up for something like this: 

while (yourcontainer.has_next?) do
  item = yourcontainer.get_next 
  # do stuff with item here
end
# If that's the case, you don't need an IterableContainer class. 
# The functionality is built-in with arrays, and looks like this:

yourarray.each do |item|
  # do stuff with item here
end

# If having access to the index is necessary, you can do that too:

yourarray.each_with_index do |item, index|
  # do stuff with item and index here
end
1b491994d6011d720e332af6e1ffd03b

bruno antunes

August 7, 2009, August 07, 2009 08:39, permalink

No rating. Login to rate!

The thing is: in my rudimentary plug-in system, I want the plug-ins to be able to access data structures from the "main" program, and do it in a generic way. By "hiding" it in a different class, I can iterate them. But yes - "each" seems like the best way to do it. Thanks, lordzoner!

B16194fad1e2f06697e7dac59d56b5d2

Craig Ludington

August 8, 2009, August 08, 2009 18:39, permalink

No rating. Login to rate!

I like the each version but it seems that the idea of a circular buffer got left behind.
This might be less idiomatic, but it maintains the circular buffer semantics of the original.

# Implement a constant circular buffer.
class CircularBuffer
  BUFFER = [:north, :east, :south, :west] unless defined? BUFFER
  STOP   = BUFFER.length - 1              unless defined? STOP
  @@i    = -1 # current offset is always incremented before use

  # Return true if the current value is at the end 
  # of the buffer, false otherwise.
  def self.at_end?
    @@i == STOP
  end

  # Return the value of the buffer at the current offset, 
  # cycling around to the beginning if the end of the buffer 
  # is reached.
  def self.current
    return BUFFER[ @@i ] if (at_end? and @@i = 0) or (@@i = @@i + 1)
  end
end

raise "at_end? was true the first time it was called"      if     CircularBuffer.at_end?
raise "current wasn't :north the first time it was called" unless CircularBuffer.current == :north
raise "current wasn't :east the second time it was called" unless CircularBuffer.current == :east
raise "current wasn't :south the third time it was called" unless CircularBuffer.current == :south
raise "current wasn't :west the fourth time it was called" unless CircularBuffer.current == :west
raise "at_end? was false when curent was :west"            unless CircularBuffer.at_end?
raise "current wasn't :north the fifth time it was called" unless CircularBuffer.current == :north
F30b04ed4d0b3fc4bc791a28815f34ca

ReinH

September 9, 2009, September 09, 2009 18:11, permalink

No rating. Login to rate!

I'm not sure that this can be significantly refactored. Ruby doesn't have a circular linked list class. #each is not equivalent in behavior. Here's the only thing I can see to refator:

def self.get_next
  @i += 1
  @i = 0 if @i >= CONT.length # fix bug where @i == CONT.length
  CONT[@i]
end
56eefae0b220faf6f276949a3fd44547

Russell

November 6, 2009, November 06, 2009 17:14, permalink

No rating. Login to rate!
b = [:ip,:al]
c = b.shift; b << c

Your refactoring





Format Copy from initial code

or Cancel