Logical Operators and the Range Operator

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