[ LiB ] | ![]() ![]() |
One great bonus to learning similar languages at once is the overarching familiarity that comes with common elements. All programming languages have some similar features, and these three languages in particular are based on similar premises and ideas. This makes it possible to share the learning curve, so to speak. Python, Lua, and Ruby share the following particularly important programming elements:
Comments and commenting
Math and algebraic functions
Variables
Lists and strings
Program structure
All modern programming languages allow programmers to insert comments into their code. Comments are extremely important, not only to the professional who needs to write code that other people may need to change or maintain, but also to individuals or independent programmers who need to look at their code again at some point in the future to see how they did something or modify an existing program.
Most languages reserve the use of the pound sign (#) to designate a one-line comment. You will find the # symbol used in this way in AWK, Perl, PHP, and C, but most importantly for us, in both Python and Ruby. Here is an example of commenting in Python and Ruby:
PYTHON RUBY # This code sample has only comments # The computer, compiler, or interpreter will for the most part # Ignore all of these lines # Simply because they start with a pound sign
Lua has its very own comment designator: two dashes in a row (--). Here is an example:
LUA
-- This code sample has only comments
-- The computer, compiler, or interpreter will for the most part
-- Ignore all of these lines
-- Simply because they start with dashes
When it comes right down to it, your computer is speaking a language of 0s and 1s. It's no surprise, then, that math tools, functions, and operators tend to be similar across all languages. You can pretty much bank on functions like add (+), subtract (-), multiply (*), and divide (/) being available no matter what programming language you are using.
Another commonality between Python, Lua, and Ruby is using parentheses () to state precedence; this comes right out of high school algebra. For instance, the answer to this code example will be different depending on the order of operations: 1+2*3 = X.
If you perform the operations from left to right, X will equal 9, but if you do it from right to left, X will equal 7. Python, Lua, and Ruby (along with many other languages) use parentheses to specify the order in which computations should be performed if you wish to override the natural order of operations. If you needed to specify that you multiply before adding in the following example, you can use parentheses around the multiplication, forcing the multiplication to be computed before the addition:
1+ ( 2*3 ) = X
Parentheses are often used with other programming structures to perform comparisons and to make decisions during the program flow. Understanding how to pose and evaluate comparisons is a crucial skill for any programmer or computer scientist. Because they are so often used, many different types of comparisons have been developed.
A mathematician named George Boole invented boolean algebra in the nineteenth century. boolean Algebra only has two values: True and False (this is sometimes called two-valued logic). It may be difficult to balance your checkbook with boolean algebra, but it's extremely easy to create decision and logic trees with it.
Boolean expressions often involve comparison operators to help evaluate truth or falsehood. Operators such as equal (=), less than (<), and greater than (>) should look familiar to you if you didn't skip your high school math classes. These constructs are so common and useful that many languages use them. Python, Lua, and Ruby all use the same comparison symbols, illustrated in Table 2.1.
Comparison operators are normally used to form expressions that can be evaluated as True or False. For example:
1 < 2 - Evaluates to TRUE 1 > 2 - Evaluates to FALSE 1 = 2 - Evaluates to FALSE
Sometimes you need to make comparisons in groups. A program may need to ask, "Is player character one an Elf AND a Wizard?"
Player1 = (Elf AND Wizard)
Typical comparisons use logical structures: logical AND, logical inclusive OR, and logical NOT. Logical AND along with logical OR are used to combine conditions or statements. lua and Python try to keep the constructs simple for the reader by using common English words, as do most high-level languages, including Eiffel, Ada, Smalltalk, Lisp, and Perl. You can designate logical AND, OR, and NOT by using the command words and, or, and not, respectively.
Ruby takes a slightly different course and follows convention, using the same programming symbols that the popular c family (C, C++, and C#) uses to designate AND, OR, and NOT: &&, ||, and !. These differences are also illustrated in Table 2.1.
The logic constructs AND, OR, and NOT are normally used with boolean True and False to form simple and complex programs. These constructs are sometimes called Boolean operators.
Boolean operators are evaluated differently when in combination with each operator. For the AND operator, the combination of two True values results in True; all other combinations evaluate to False, as illustrated in Table 2.2.
Operators | Evaluation |
---|---|
True AND True | Evaluates to True |
True AND False | Evaluates to False |
False AND True | Evaluates to False |
False AND False | Evaluates to False |
For the OR operator, as long as one of the values is True, then the expression evaluates to True, as shown in Table 2.3.
Operators | Evaluation |
---|---|
True OR True | Evaluates to True |
True OR False | Evaluates to True |
False OR True | Evaluates to True |
False OR False | Evaluates to False |
The NOT operator is called the complementary operator. It reverses the truth-value, as shown in Table 2.4.
Operators | Evaluation |
---|---|
NOT True | Evaluates to False |
NOT False | Evaluates to True |
Once you understand boolean logic, comparison operators, and logical structures, you can create very complex decision trees, like this:
# The following line evaluates to boolean FALSE (((1+2)*5) =11) and ((5*6) != (7*6)) # The Following line evaluates to boolean TRUE ((1+1) = 5) or ((5*6) = 40 and ((5/4) = 2*.5)) or ((50/5) = 10)
Function | Python Command | Lua Command | Ruby Command |
---|---|---|---|
Add | + | + | + |
Subtract | - | - | - |
Multiply | * | * | * |
Divide | / | / | / |
Equal (assignment) | = | = | = |
Equal To | == | == | == |
Less Than | < | < | < |
Greater Than | > | > | > |
Logical NOT or Not Equal To | not | not | ! |
Logical AND | and | and | && |
Logical OR | or | or | || |
Square Root | sqrt | sqrt | sqrt |
Exponent | exp | exp | exp |
Absolute Value | abs | abs | abs |
Basic Sin | sin | sin | sin |
Cosin | cos | cos | cos |
Tangent | tan | tan | tan |
Logarithm | log | log | log |
Truncate/Round | round | round | round |
Floor | floor | floor | floor |
Ceiling | ceil | ceil | ceil |
Power | ** | ^ | ** |
Computers and computer programs manipulate data. Variables are holders for data any computer or program might need to use or manipulate. Variables are usually given names so that a program can assign values to them and refer to them later symbolically. Typically a variable stores a value of a specific given type like:
An integer or whole number
A real or fractional number
A character or a single letter of an alphabet
A string or a collection of letters
Many languages need to know in advance what type a variable will be in order to store it appropriately. Since computers are finite in memory, there are often several different numerical designations, depending upon how big a number can grow or how that number needs to be represented in binary.
Others languages are more flexible in dealing with variables; this is called dynamic typing, as I mentioned in Chapter 1, and is a common high-level language feature. Even with dynamic typing, most programmers declare variables at the start of their program out of convention. This consists normally of dreaming up a name and then declaring a data type for the variable. Typical variable types are listed and described in Table 2.5.
Variable type | Description |
---|---|
Boolean | Holds only True or False |
Float | A number with a decimal point (floating decimal point) |
Integer | A whole number |
Null | No value |
String | Ordered sequence of characters |
Each language's variable types and how to use them are explained in more detail in their respective sections in this book, but there are a few commonalities I will mention here. For instance, null values are symbolized by nil in both lua and Ruby, while Python uses the designation none. Both nil and none are treated as false in a boolean sense.
PYTHON # This assigns x a null or boolean false value in Python X = none RUBY LUA # This assigns x a null or boolean false value in Ruby or Lua X = nil
A second example of similarity with variables is that Python and Ruby both use the value method to grab the value of a variable.
PYTHON RUBY # this code snip uses the value method to return the value of x x = 4 # This line grabs x and prints it in Python print x.value # This line grabs x and prints it in Ruby $stdout.print(x.value)
NOTE
CAUTION
Many popular languagesfor instance C, C++, and Perlalso use zero (0) as boolean false. This is not necessarily the case in High-Level Land. For instance, in Ruby, anything not designated as nil or false is automatically true in the Boolean sense, even the number 0. This switch sometimes tricks converts from other languages.
Although similar in some ways, Python, Lua, and Ruby differ significantly in how they handle variables and types. They each follow slightly different paradigms that create differences on a basic level. These differences will become apparent as you delve into each language in the chapters that follow.
Lists are used to group things together. They are data structures designed to make life easier for the programmer. A list is simply a row of variables or data elements. They can be composed numbers, letters, or even constructs such as arrays, hashes, or even other lists. Lists are created in Python and Ruby by using brackets []:
PYTHON RUBY #To create a list called lista with the numbers 8-n-1 through 10, just put them in brackets and separate them with commas: lista = [1,2,3,4,5,6,7,8,9,10]
You can use the + symbol in each language to concatenate lists together:
PYTHON RUBY # To combine fish and chips list a with list b lista = [1,2,3,4,5] listb = [6,7,8,9,10] # Just add them together into a new list newlist = lista+listb
Since not all languages have direct support for strings, one of the time-saving features that high-level programmers often enjoy is built-in string handling. Not only are there common commands for working with strings, the memory management of strings is usually handled automatically.
A strings is basically just a list of characters. To get Lua, Python, or Ruby to recognize a string verbatim, you can place it between single parentheses, like so:
PYTHON LUA RUBY # Python, Lua, and Ruby will recognize this as a string 'Enclose strings like this in single quotes'
You can also use math functions to make string comparisons in Python and Ruby, just like you can with lists. For instance, the + sign can be used for string concatenation with Python or Ruby, like so:
PYTHON RUBY # to combine the strings 'fish', 'and', 'chips' stringa = 'fish' stringb = 'and' stringc = 'chips' stringd = stringa+stringb+stringc
You will find that equal to (==) and not equal to (!=) are often used to compare different strings as well:
PYTHON RUBY # Is the password 'Enter' ? # First, get the password If password = 'enter' # Then you shall pass If password != 'enter' # Then no such luck
Arrays are similar to lists. They are both used for storing items or lists of items, but they keep 9-track of the items in different ways. Arrays organize lists of items by a numeric index, an extremely powerful tool in programming.
Although each of these languages handles lists in a similar way, they have somewhat different approaches for arrays. Ruby has a built-in array method, but, strictly speaking, lua does not have built-in arrays and substitutes for them with table structures. Python has its own version of arrays called sequences.
Despite the differences, these languages handle arrays in similar ways. An example is the sort method or command. Ruby uses sort to put in order items within a hash or array, lua uses sort to order a table, and Python uses sort to order a list. Similarities like these run deep through these languages, but can become confusing and difficult to wade through when switching between them frequently.
All programming languages have some sort of structure or flow to them. Most programs share a structure similar to that in Figure 2.1. Normally there is a statement that establishes the beginning of a program, then variables are declared, and then there are code blocks, which are also called program statements.
Program statements provide the control of a program. They usually act as decision trees, executing different sections depending upon the input given. Figure 2.2 illustrates a structured-programming graph in which the ovals represent starting and ending points, the squares represent program blocks, and the diamond represents a decision to be made in the program that will send the flow down one of two branches.
Program statements come in a couple of different forms. So far in this book, I've used mostly simple statements. Simple statements are short expressions that perform specific actions. There are also compound or complex statements that generally consist of more than one line of code and use many expressions.
Statements that control which sections of code are to be executed are called control statements (surprise!) and consist of a few basic types.
Linear Control Statements. Control is based on a logical sequence, and code is executed in the default order as it's listed in the source file.
Conditional Control Statements. A condition is set that makes a decision on which block of code is to be executed.
Iterative Control Statements. Blocks of code may be executed more than once in loops.
Linear control statements are the most intuitive of type of program structure. In linear control, commands are executed in a sequential, ordered, linear manner. This usually equates to running one line at a time, like so:
Start Program Run Command 1 Run Command2 Run Command3 End Program
Since English-speaking humans are most comfortable reading from left to right and from the top down, the same conventions are used in linear control.
Statements that are considered conditional are often referred to as if/else statements. The commands if and else determine which lines or blocks of code might or might not run, depending on the flow of the program. Programmers generally use these as branches to initiate actions that are dependent on user input.
The if command is the foundation of all conditional statements. if checks a specified condition for truth value. If the condition is true, then if executes a code block that follows. If the condition is not true, the code block is skipped.
if (this condition is true) (then this happens)
Figure 2.3 depicts the flow of a program going through an if statement. The flow goes through the diamond branch, which executes the code block (the square) if the condition is true or continues to the ending oval if the condition is false.
Python uses if for command flow in the following way:
PYTHON
# Examples of and if statement checking the truth of X being greater than 90 in Python if X > 90
Then do this
Ruby and lua are similar, but use an end command to designate the end of an if structure.
RUBY LUA if X > 90 then do this end
The else command is another common conditional that can follow an if statement. When an if statement returns a value of false, the code block held by else executes. This creates a fork in the program, where either the if block or the else block is executed. When using else and if together in Python, Ruby, or Lua, the general syntax looks something like the following:
if (this condition is true) then this happens else (this happens instead)
This series of if and else statements allows code to make decisions based on variables or input. When the program flow has two possible execution choices, it is known in structured programming as a double selection. The if/else statement is illustrated in Figure 2.4.
A double selection can be limiting because there are only two forks that the program can take. If you need to program for multiple paths, you can use the elsif command in Ruby, the elseif command Lua, or the elif command in Python, all of which are equivalent.
You can use multiple elsif/elif statements in a row to create one long string of conditions for which to check. However, only one else statement can follow an if. The syntax for these statements looks like the following:
if (this first condition is true) (then this first program block runs) elsif/elseif/elif (this second condition is true) (then this second program block executes) elsif/elseif/elif (this third condition is true) (then this third program block runs) else (this fourth block fires instead)
As we get deeper into each language, each will start to have its own distinct flavor, and they will begin to appear different. You can see how different in the following code, which displays the typical elsif/elif/elseif flow in each language. Figure 2.5 also shows a typical elsif/elif/elseif program structure.
PYTHON # Example of elif In Python If X > 90 print "this" elif X < 90 Print "this instead" Else: Print "this" LUA # Example of elseif In Lua if x>90 then blocka {elseif x<90 then blockb} [else blockc] end RUBY # Example of elsif in Ruby if x > 90 then this blocka fires elsif x < 90 then this blockb fires else blockc fires end
Programming languages must have a facility to allow sections of code to be repeated, or iterated. Iteration is possibly a computer's greatest strength. There are several variations of constructs that are used to iterate program blocks; these are commonly called loops.
The for loop is probably the most common loop in programming. It takes a few separate conditions to execute and takes on the following general structure:
for (the length of this expression) (execute this code block)
Figure 2.6 shows the structured program flow of a for loop. Notice that there are two programming blocks: the first is the code that executes as part of the loop expression, and the second is the block that the loop executes.
Although iteration commonly is needed when programming, and a built-in for construct exists for each of these languages, each has its own peculiarities.
Python's for loop uses a counter and a range to determine how many times to loop a given code block. The counter is incremented each iteration of the loop until the counter reaches the end of the range and the loop is complete.
PYTHON for counter in range ( X ): block To create a for loop in Python that loops 10 times, do the following: PYTHON for counter in range ( 10 ): block
Lua's for statement works in the same principal way but has two forms, one for numbers and one for tables. The numerical for loop has the following syntax:
LUA
for name '=' exp1 ',' exp2 [',' exp3] do block end
The first expression (exp1) is the counter, the second (exp2) is the range, and the third (exp3) is the step (the step is automatically a step of 8-n-1 if omitted). Therefore, a for loop in lua that would run a block 10 times would look something like the following:
LUA for name = 8-n-1 ,10, 8-n-1 do block end
Ruby has a unique way of dealing with for loops, and iterators in general. Ruby uses a number of predefined classes with built-in methods to provide iteration functionality. There are several ways to accomplish the same 10-iteration loop in Ruby:
RUBY
10.times do
block end
Or
RUBY
1.upto(10) do
block end
Ruby also has a comparable for/in construct with a similar structure:
RUBY
for i in 1..10
block end
and a built in loop iterator that looks this:
RUBY
i=0
loop do
i += 1
next if i < 3
block break if i > 4
end
A second common loop is known as the while loop (sometimes known as the do/while loop). A while loop is normally used to keep a section of code continually running while a certain condition is true. The flow of this loop is shown in Figure 2.7.
The while loop takes on the general structure of:
while(this statement is true) do (execute this block)
Each language, again, has its own nuances, but the while loop looks fairly similar in each.
Python's while loop is almost identical to the for loop:
PYTHON
X = 100
while X < 100:
block
Note that these examples could execute a never-ending loop unless a way to increase x was added.
Lua's while is almost identical to Python's, but with substitution of parentheses for the end colon and the addition of an end:
LUA
while ( X> 100) do block end
Ruby's while is also almost identical to Python's:
RUBY
while X < 100
block end
As you read through this book, you will find more and more similarities between the languages. In addition to commenting, mathematics, lists, variables, and program structure, there are a number of other significant similarities. Some of these I will point out as the book progresses, and others you'll discover on your own. A few of the more significant ones are illustrated in this section. Table 2.6 lists a few miscellaneous commands that have similar or the same names.
Function | Python Command | Lua Command | Ruby Command |
---|---|---|---|
Access read/write | a[e] | a[e] | a[e] |
Runtime evaluation | eval | dostring | eval |
Duplicate n times (string repeat) | * | strrep | * |
ascii to character | chr | strchar | chr |
Value | v | v | v |
Knowing where a command line ends is important for understanding program flow. One line of code is usually over at the end of the line, when a return is entered. The end of a line may also end in an "End of line" command such as a colon (): or semicolon (;). Python and Ruby both use the semicolon symbol as an end of line command to end a statement; in lua the semicolon is optional. In Python and Ruby you can also simply use an end of line character (or a return).
# Sample of an end of the line statement This code line ends at the semicolon; This is a second, separate line of code;
Breaking up a line is useful if the line is too long and you need to go on to the next line. Both Ruby and Python both use the \ (backward slash) to signify that the command goes on to the next line.
PYTHON RUBY # Sample of using a \ to extend a line of code This code line ends at the semi colon; This snippet goes on to the next line\ And ends here
Since each of these languages is object oriented to some degree, and they are all based on similar strategies, it follows that they possess similar object-oriented constructs. This is especially true for Python and Ruby, whose commands for method invocation, class declaration, and scope are identical. In fact, method invocation (and scope) uses a very recognizable structure for OOP veterans:
object.method(parameter)
As you can see, the . operator is used to define scope as well as a record selector. The command class is also used to designate a class in both languages.
All three languages have similar commands for function calls, the typical syntax being:
function(parameters)
In Ruby, you can call a function without any parameters just by naming it:
function
In lua and Python, you must still specify that there are no parameters with parentheses:
function()
The command return is used by Ruby and Python to break the function control flow and return a value.
[ LiB ] | ![]() ![]() |