A couple of nights ago, I attended a training session on Ruby that was held at Launch Academy in Boston. I met one of the co-founders a week earlier, so I checked out their web site and found this among the events. With the time slot wide open, it made sense to make the trip and gain something more on a language that has gained in popularity, although it did a little more for me than that.
Ruby has become popular in part because of the Rails framework that makes it a very appealing choice for the Web (Ruby on Rails). Aside from that, it is in the same class of languages as Tcl, Perl and Python as an interpreted language and one useful for a number of purposes, though you might not use it for many of the same projects on which you would choose C, C++ or Java.
We went through a lot of the basics, including conditionals, leaving off before getting to looping. As has often been the case, my intuition built up from learning several other languages helped me to pick up many aspects of it, so it came relatively easily. The interesting part came when we did the big challenge program, one that used all of the concepts we had covered to that point.
There is really just one aspect of it that is noteworthy. The user enters in a choice, and the program then executes based on it, with a few if-else cases to take care of. One possibility when there is user input is that the user enters an input that is no good – for example, if the program wants the user to enter a number but the user enters a letter, or if the user enters a number that is too big or too small, or a zero when the input will be used in division.
My intuition, largely built up from years of C and C++ programming, is to check the user input right away. See if the user entered something with which the program may continue; in some programs this means checking arguments as well to make sure there were not too few or too many. By doing this, you not only avoid the possibility of program errors from using a bad value (such as a divide by zero if the user enters zero for something that will be a denominator), but you also avoid using processor cycles to go further into the program than you need to.
I attempted to do just that – to check the inputs right away for a bad value. I accounted for the three good values the user could enter, then wanted to handle the bad one and exit in the event of it. However, Ruby does not have a graceful exit that I could find right away. It does have an exit call, which does exit the program, but not gracefully. If you use repl.it to run such a program, you get some feedback that tells you as much.
Instead, the way to handle this is to determine if the input was invalid, and when doing the last set of conditionals, check the input one more time and then handle it. Handling the last sequence is a little different as well, given the added conditional.
We didn’t get to talk about looping, but I went and did an exercise of my own after looking through the material. An old favorite is the factorial, which for those not familiar is multiplying a number by every number counting down until 1. For example, the factorial of 4 (denoted as 4!) is 4 *3 *2 *1 = 24 and 5! is 5 * 4 * 3 * 2 * 1 = 120. The code that does this work, starting with the user input, is mostly straightforward:
# Compute the factorial of a number entered by the user
# First, prompt the user for the number
puts “Enter a number to compute the factorial of: “
number_entered = gets.chomp
# Convert to an integer, then initialize our result
thenumber = number_entered.to_i
result = 1
# Now compute the factorial, decreasing every time through
while thenumber > 0 do
result *= thenumber
thenumber -= 1
end
It is worth noting that I have seen a C implementation of this as a recursive function, which is certainly not what is being done here and has other considerations. In part, that is because the C implementation I allude to was as a function to be called elsewhere, whereas in this instance the program’s purpose to compute and return a factorial.
At the end, we want to display the result. But how do we handle the user giving a bad input, such as a negative number? We could do it early on, and that would be my instinct. Using what I know now, though, here is the end:
if thenumber < 0
puts “User entered a value less than 1 – factorial is N/A”
else
puts “The factorial of #{number_entered} is #{result}.”
end
So there is something to be gained from this – namely, that while it might be nice to exit immediately if you know you have input you can’t deal with, sometimes that convenience isn’t available to you and you have to improvise.
Generally speaking, one can learn the syntax of a language quickly if they know another programming language. Some real-world programming accelerates it. From the examples in the class and what I did on my own, I feel like I am off and running with Ruby and look forward to learning and using it more in the future. I also like how it made me think a little bit about my approach to handling bad inputs.