reitermarkus reitermarkus - 6 months ago 8
Ruby Question

What's the best way to refactor redundant each/reverse_each code in Ruby?

I have implemented these

each
and
reverse_each
methods for a doubly-linked list.

What would be the best way to refactor this?

def each
return enum_for(:each) unless block_given?
node = self
until node.nil?
yield node
node = node.next
end
end

def reverse_each
return enum_for(:reverse_each) unless block_given?
node = self
until node.nil?
yield node
node = node.prev
end
end

Answer

The easiest way to remove redundant code is to move it to a new method.

Something like this should work:

def each(&block)
  return enum_for(:each) unless block_given?
  traverse(:next, &block)
end

def reverse_each(&block)
  return enum_for(:reverse_each) unless block_given?
  traverse(:prev, &block)
end

private

def traverse(direction)
  node = self
  until node.nil?
    yield node
    node = node.send(direction)
  end
end