IT-SC 216
Split the two or three if includes parenthesized name fields
my fields = split , _; Get and store the name and the recognition site
Remove parenthesized names, for simplicitys sake, by not saving the middle field, if any,
just the first and last name = shift fields;
site = pop fields; Translate the recognition sites to regular
expressions regexp = IUB_to_regexpsite;
Store the data into the hash rebase_hash{name} = site regexp;
} Return the hash containing the reformatted REBASE
data return rebase_hash;
}
This parseREBASE subroutine does quite a lot. Is there, however, too much in one subroutine; should it be rewritten? Its a good question to ask yourself as youre writing
code. In this case, lets leave it as it is. However, in addition to doing a lot, it also does it in a few new ways, which well look at now.
9.2.4 Logical Operators and the Range Operator
Youre using a foreach loop to process the lines of the bionet file stored in the rebasefile
array. Within that loop you use a new feature of Perl to skip the header lines, called the range
operator .., which is used in this line: 1 .. Rich Roberts and next;
This has the effect of skipping everything from the first line up to and including the line with Rich Roberts, in other words, the header lines. Range operators must have at least
one of their endpoints given as a number to work like this.
The and function is a logical operator. Logical operators are available in most programming languages. In Perl theyve become very popular, so although we havent
IT-SC 217
used them a great deal in this book, youll often come across code that does. In fact, youll start to see them a bit more as the book continues.
Logical operators can test if two conditions are both true
, for instance: if string eq kinase and num == 3 {
... }
Only if both the conditions are true
is the entire statement true
. Similarly, with logical operators you can test if at least one of the conditions is
true using the or operator, for instance:
if string eq kinase or num == 3 { ...
}
Here, the if
statement is true
if either or both of the conditionals are true
. There is also the not logical operator, a negation operator with which you can test if
something is false
: if not 6 == 9 {
... }
6 ==
9 returns
false , which is negated by the not operator, so the entire conditional
returns true
. There are also the closely related operators,
for and, ||
for or, and for not. These
have slightly different behavior actually, different precedence; most Perl code uses the versions Ive shown, but both are common.
When in doubt about precedence, you can always parenthesize expressions to ensure your statement means what you intend it to mean. See
Section 9.3.1 later in this chapter.
Logical operators also have an order of evaluation, which makes them useful for controlling the flow of programs. Lets take a look at how the and operator evaluates its
two arguments. It first evaluates the left argument, and if its true
, evaluates and returns the right. If the left argument evaluates to
false , the right argument is never touched.
So the and operator can act like a mini if
statement. For instance, the following two examples are equivalent:
if verbose { print helpful_but_verbose_message;
}
IT-SC 218
verbose and print helpful_but_verbose_message; Of course, the if statement is more flexible, because it allows you to easily add more
statements to the block, and elsif and else conditions to their own blocks. But for simple situations, the
and operator works well.
[1] [1]
You can even chain logical operators one after the other to build up more complicated expressions and use parentheses to group them. Personally, I dont like that style much, but
in Perl, theres more than one way to do it
The logical operator or evaluates and returns the left argument if its true
; if the left argument doesnt evaluate to
true , the or operator then evaluates and returns the right
argument. So heres another way to write a one-line statement that youll often see in Perl programs:
openMYFILE, file or die I cannot open file file: ; This is basically equivalent to our frequent:
unlessopenMYFILE, file { print I cannot open file file\n;
exit; }
Lets go back and take a look at the parseREBASE subroutine with the line: 1 .. Rich Roberts and next;
The left argument is the range 1 .. Rich Roberts
. When youre in that range of lines, the range operator returns a
true value. Because its
true , the
and boolean
operator goes on to see if the value on the other side is true
and finds the next function, which evaluates to
true , even as it takes you back to the next iteration of the
enclosing foreach loop. So if youre between the first line and the Rich
Roberts line,
you skip the rest of the loop. Similarly, the line:
\s and next; takes you back to the next iteration of the
foreach if the left argument, which matches
a blank line, is true
. The other parts of this parseREBASE subroutine have already been discussed, during the
design phase.
9.2.5 Finding the Restriction Sites