Home > Articles > Programming > Ruby

  • Print
  • + Share This
Like this article? We recommend

Having Some Fun with Ruby

Writing single classes, although instructive, is just part of a bigger picture. Useful software arises from the interaction of many different objects, and so to illustrate this the CircularCounter class will be used to create an Odometer. Just for fun, the Odometer will be configurable as to which number base it will use, and each wheel on the Odometer will be represented by a kind of CircularCounter. Like all toy problems, this design could be drastically improved, but it demonstrates inheritance and some of the more esoteric functionality of the Array class.

The first thing to do is save the definition of the CircularCounter class in a file called CircularCounter.rb, and then create an OdometerWheel.rb file containing the following definition:

class OdometerWheel < CircularCounter
 def initialize (limit, initialValue, nextWheel)
  super (limit,initialValue) #invoke parent constructor
  @nextWheel = nextWheel
 end
 def increment
  if (super) #invoke superclass version of increment
   nextWheel.increment
  end
 end
end

Once that's in place, the Odometer class itself is relatively simple to create (in Odometer.rb), even if the collect! idiom does require a bit of thought and a scan through the Array documentation:

class Odometer
 def initialize(size,base)
  @wheels = Array.new(size)
  @wheels[0] = CircularCounter.new(base,0)
  prev = @wheels[0]
  @wheels.collect! { |elem|
   if (nil == elem)
     elem = OdometerWheel.new(base,0,prev)
     prev = elem
   else
     elem = prev
   end
  }
 end
 def increment
  @wheels.last.increment
 end
 def reading
  val =""
  @wheels.each{|elem| val = val + elem.value.to_s }
  val
 end
end

Once this is in place, a simple test script can validate that everything is working as expected:

require "CircularCounter.rb"
require "OdometerWheel.rb"
require "Odometer.rb"
# decimal Odometer
o = Odometer.new (6,10)
12345.times { o.increment }
p o.reading
# Binary odometer
bin = Odometer.new (8,2)
32.times { bin.increment }
p bin.reading

With this script in a file called OdometerTest.rb, it can be executed directly in interactive Ruby:

D:\Ruby\bin>ruby irb
irb(main):001:0> require "OdometerTest.rb"
"012345"
"00100000"
true
irb(main):002:0> exit

The script can also be run as a normal Ruby script:

D:\Ruby\bin>ruby OdometerTest.rb
"012345"
"00100000"
D:\Ruby\bin>
  • + Share This
  • 🔖 Save To Your Account