1
\$\begingroup\$

I'm working alone on my code, trying to learn Ruby as I go.

Class Robot is supposed to be instantiated with the position on a map, and whether it is facing toward a side of the map. It has a couple of moves: left or right, where the face of the robot changes direction, and a move action, one step forward.

class Robot
 def initialize(pos_X, pos_Y, facing)
 @pos_X, @pos_Y, @facing = pos_X, pos_Y, facing
 end
 def move
 world_switch(Proc.new { @pos_X += 1}, Proc.new { @pos_X -= 1},
 Proc.new { @pos_Y += 1}, Proc.new { @pos_Y -= 1})
 end
 def left
 world_switch(Proc.new {@facing = 'WEST'}, Proc.new {@facing = 'EAST'},
 Proc.new {@facing = 'NORTH'}, Proc.new {@facing = 'SOUTH'})
 end
 def right
 world_switch(Proc.new {@facing = 'EAST'}, Proc.new {@facing = 'WEST'},
 Proc.new {@facing = 'SOUTH'}, Proc.new {@facing = 'NORTH'})
 end
 def report
 puts "Output: " << @pos_X.to_s << ',' << @pos_Y.to_s << ',' << @facing
 end
 def world_switch(do_on_north, do_on_south, do_on_east, do_on_west)
 case @facing
 when 'NORTH'
 do_on_north.call
 when 'SOUTH'
 do_on_south.call
 when 'EAST'
 do_on_east.call
 when 'WEST'
 do_on_west.call
 end
 end
end
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Oct 2, 2012 at 12:38
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

Looks like you over-thought it a little bit. Callbacks are indeed a powerful abstraction, but it looks overkill in this case. Some notes:

  • Use symbols to codify @facing: :east, :north, ...
  • a hint to write move without callbacks:

    increments = {:north => [0, +1], :east => [+1, 0], :south => [0, -1], :west => [-1, 0]}
    
  • A hint to write left without callbacks:

    new_facing = {:north => :west, :east => :north, :south => :east, :west => :south}
    

This way you describe what the robot does not with code (callbacks) but with data structures (which can be as simple as a hash).

As requested: the complete implementation of left:

def left
 new_facing = {:north => :west, :east => :north, :south => :east, :west => :south}
 @facing = new_facing[@facing]
end
answered Oct 3, 2012 at 8:34
\$\endgroup\$
1
  • \$\begingroup\$ +1 to write the code without callbacks (in this case def) But can't understand how 'new_facing' will be implemented, please look at the implementation file posted later: codereview.stackexchange.com/questions/16109/… \$\endgroup\$ Commented Oct 3, 2012 at 8:51
2
\$\begingroup\$

You should definitely apply tokland's suggestions. Additionally:

  • Don't use String concatenation (<<, +, +=), use interpolation ("the value is: #{value}") it's more readable, and faster

  • Make private methods private, in this case world_switch, but after the refactor, it should already be gone :)

  • I'd rename report to to_s this has two advantages:

    • it's the 'natural' method to call when you want a String representation of something
    • it is implicitly called when using String interpolation: "my robot: #{@robot}" # no need for @robot.to_s
  • You could also replace report by using @robot.inspect, this will give you the standard String representation for your Robot

answered Oct 25, 2012 at 0:46
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.