Bionic Commando
Friday, September 30th, 2005I don’t know if you ever played the NES game, “Bionic Commando”, but that was a fun fun game.
I don’t know if you ever played the NES game, “Bionic Commando”, but that was a fun fun game.
In one of the (non-Ruby) applications I maintain, there is a function that is responsible for handling unit conversions. It looks something like this:
double UnitConvert(double value, string from_unit, string to_unit)
So that I can do this:
double value = UnitConvert(5.0, "feet", "inches")
The underlying part of this code has to figure out exactly how to convert between the two units. In a nutshell, there’s a big hash of known unit conversions that gets loaded when the program starts up, and it can interpolate, trace paths, and figure out how to fill in any gaps that may exist. In all actuality, it’s a pretty smart piece of code.
It works due to the assumption that in order to convert between units, you just multiply by some scaling factor:
double factor = CalculateScalingFactor("feet", "inches")
# factor = 12.0
But what about units that don’t work this way? One obvious one that comes to mind is Farenheit to Celsius, which isn’t a direct scaling but also has an offset. You could do something like this:
pair<double ,double> = CalculateScalingFactor("celsius", "fahrenheit")
That takes care of this rogue case, but it doesn’t handle more complicated cases where there could be 2nd or 3rd order terms, or other tricky things like sines, logarithms, and exponentials.
This is where the power of the lambda really shines. Instead of returning some representation of the scaling factors required to do the conversion, why not return an anonymous function that handles the conversion for you.
Consider this piece of Ruby code:
# Conversion from Celsius to Farenheit
l = lambda { |x| x * 1.8 + 32 }
irb> l.call(0)
=> 32.0
irb> l.call(100)
=> 212.0
So now, instead of trying to return an array or more complex representation of conversion coefficients, we can simply return a lambda function that performs the conversion for us.
def convert(from,to)
if(from == :feet and to == :inches)
return lambda { |x| x * 12.0 }
elsif(from == :celsius and to == :farenheit)
return lambda { |x| x * 1.8 + 32 }
elsif(from == :moles and to == :millinewtons_per_square_widget)
return lambda { |x| x * Math.sin(x) * Math.exp(-x) + 33.2 }
else
raise "Unknown Conversion"
end
By calling this method, we get back a closed off lambda function in which we don’t have to worry about the details.
All that’s left is to call the function with the appropriate argument, and our converted value will be returned.
l = convert(:from_unit, :to_unit)
converted_value = l.call(some_value)
Very nice!
In Ruby, when you’ve got to grab some user input, a quick way of doing it is with a gets:
puts "What is your name?"
name = gets
puts "Hi #{name}"
But, we can make the interaction so much more pleasant through QtRuby:
require 'Qt'
Qt::Application.new(ARGV)
ok = Qt::Boolean.new
name = Qt::InputDialog::getText(”My Application”, “Enter your name”,
Qt::LineEdit::Normal, nil, ok)
if(!ok.nil?)
puts “Hi #{name}”
else
raise “The user didn’t put in a name”
end
The above code makes a much nicer dialog box:

Or, consider it when having a user enter a password:
name = Qt::InputDialog::getText("My Application", "Enter your password",
Qt::LineEdit::Password, nil, ok)

Qt::InputDialog is a convenience class for getting a quick user response - there are methods available for getting integers, floats, and items from a combo box. Of course, you can make much more sophisticated dialogs as well, but for getting a quick bit of input this class is very handy.
Whenever my company receives a new project, many times we are requested to establish a baseline set of data, which is used as a comparison to make sure something isn’t amiss with our setup.
Rapid GUI Development with QtRuby is now available. It’s my first “book”. I say “book” because it’s not being printed - rather, it’s PDF based book that you can purchase and use online. It’s formatted to fit the screen and designed to be computer friendly - lots of links, tags, readability, etc. The book is being released via the Pragmatic Programmers. If you aren’t familiar with them, you should really check them out. You may just learn a thing or two.
#2 book is already in the works. Details forthcoming.