Control structures are at the heart of imperative and object oriented programming. At some point, given some piece of data, either do this or that. Or do this X times, but only if Y and not Z. Without control language features to control the flow and execution path of a program, computer programs are glorified adding machines, taking data and producing set results.
The following articles give a complete picture of control structures in Ruby.
- In order for control structures to work, at some level there must be a boolean expression. A boolean expression is any expression that can be evaluated as either true or false, control structures need expressions like these to make their decisions. The primary method of generating this true or false value is the comparison operator. Boolean expressions can be combined using boolean operators to form more complex expressions.
- At the most basic level, all flow control is a conditional statement. If X then do this, else if Y then do that. This logic even powers all loops (combined with some form of jump). Ruby provides a number of conditional statements including simple if statements, its inverse the unless statement, if and unless in postfix form, as well as the ternary operator, a way of representing a simple if statement in a compact form.
- Related to the conditional statement is the case statement. The case statement in Ruby is a shorthand for a chain of if/else if statements, and is a common construct in Ruby code. At its heart is the case equality operator which allows for very expressive and flexible case statements.
- You can't program anything interesting without loops either, but Ruby has a strange concept of loops. Where most programming languages just give you really one form of loop (in C, the for/while loop), Ruby mostly leaves loop semantics up to the thing being looped over. For instance, the each method on arrays and other enumerable objects, you won't be using a language keyword to loop over your data, you'll be using a method on the data itself, passing it a block. And, if you must, Ruby does have a for loop, but it's not idiomatic Ruby to use it.
- While exceptions may be something you really only worry about when something goes wrong, they are a form of throw control. Ruby actually has two forms of exceptions, and their uses differ a little bit. You have exceptions using raise, which is what you're thinking about when you think about exceptions. They're mostly for when something goes wrong and you need to raise an exception describing the error. They can either be caught, and there are ways to correct the error (depending on the error, of course) and try the action again. But there is also throw and catch, exceptions that are not quite exceptions. This is more of a method of flow control, being able to throw an object from an inner loop, step out of several loops and conditions and catch it at a higher level. This might be useful in some very complicated coded, but in most situations they're just not needed, especially since Ruby encourages the formation of smaller, more focused methods.
- Related to flow control and mentioned in passing above is the Enumerable module. This is the mixin module that is used to implement looping over (among many other things) any type of collection in Ruby including everything from Arrays and Hashes to database query results. Another related feature is ranges, which are used to represent (usually) a range of numbers. Alone, this is not flow control, but combined with the Enumerable module it's typically how you'd iterate over a range of numbers (where in C, you'd be using a for loop and a counter variable).
Well there you have it. This is more or less everything there is to know about loops, conditional expressions, case statements and exceptions in Ruby. There's a bit more to it than other languages, but you'll primarily be using the Enumerable module to do most of the looping and the case and if statements as conditionals. There are a few things mentioned here that are certainly not idiomatic Ruby, such as throw statements (not to be confused with raise statements) and for loops. Typically you'll never see these constructs in "real" code, it's just not how you do it in Ruby.