Pluses: Viewed in its best light, Perl is a language that encapsulates the best features of the shell, sed, grep, awk, tr, C and Cobol. If you are familiar with these tools, you can write very powerful Perl programs rather quickly and easily. In particular, you can write programs that duplicate the functionality of shell scripts but are all in one file (indeed, they are all in one language) and thus are much more efficient.
Minuses: Perl is a jumble. It contains many, many features from many languages and programs. It contains many differing constructs that implement the same functionality. For example, there are at least 5 ways to perform a one-line if statement. While this is good for the programmer, it is extremely bad for everyone but the programmer (and bad for the programmer who tries to read his own program in 6 months), and has led to Perl being called a ``write-only'' language. There are other minuses as well, but I won't go into them further. You can discover them for yourself. A colleague of Dr. Plank (Norman Ramsey, at Virginia) responded to an email sent to him about perl, and his response is worth quoting in it's entirety:
So this is the mistake. The brilliance is in including so many things people want to do, and in a form that is almost familiar, so they can pattern-match more easily. In fact, the familiarity is really an illusion, and if you're going to program in perl, you can hack without understanding, or you can restrict yourself to a subset you can understand. But if you're going to do the latter, why not program in sh, awk, and sed to begin with?
I've never used apl, so I can't compare.
I have---the thing with apl is that although it is *all* weird, it is weird in a very consistent way. You don't have the illusion of familiarity. You do have a huge set of unreadable glyphs, but they come with a very small set of simple rules for decrypting them, the most important of which are the right-to-left scan rule and the fact that user-defined functions take at most two arguments.
I just got to a part in my manual where they advocate using && as an if statement.
I got past that. I gave up on perl the day I learned I couldn't write a function to return an open file handle (e.g., an open socket). Now I use it only when forced.
The debate as to which is better: Perl, Python or Icon (which I'm not teaching in this class) is a heated one. Python and Icon have better language design. Perl has the most familiar regular expression syntax. I won't get into it, but if you look, you can find all sorts of opinions. Of course, it's best to formulate your own opinions by learning all three....
There are two recommended books in case you want more. First is ``Learning Perl'' by Schwartz, and ``Programming Perl'' by Schwartz and Wall. Both are published by O'Reilly & Associates.
#this is a comment at the left margin print $red; # and this is a comment starting elsewhereNote the semicolon after the print statement. Just like in C, all simple statements end with a semicolon.
$x = 19; $str = "this is the house"; $dog = "collie"; $comment = "I love my $dog"; $pi = 3.1415; $arc = $pi * $x; $dir = `ls`; $str2 = "There are $x files in this dir\n";Note that wherever a scalar is used it is always preceded by a dollar sign. The quotation marks work pretty much as you would expect from what you know of the Bourne shell. Double quotes denote a string and substitutions are performed. Single quotes are a string but substitutions are not performed. Backquotes result in the quoted string being evaluated as though it were a command and the result is then used in the assignment. Also note that perl performs arithmetic operations without the use of an exterior utility, very handy.
To make assignments to array elements we can use the type as for scalars
$x[0] = 19; $str[2] = "this is the house"; $dog[1] = "collie"; $dog[2] = $dog[1];or we can use lists to perform the assignment to the entire array
@dogs=("collie","sheppard","hound","mutt"); @nums=(2,4,6,9); @another=(); # an empty array @dir = `ls`; # an array of the directory listingThe first form is similar to that used in most programming languages the second my not be familiar to you but is more like that used by other scripting languages. It is very handy to be able the manipulate the elements of the array as a whole. And to support this, perl carries the ability to manipulate arrays even farther. Assignments can be made from arrays (or lists) to lists containing variables.
($a,$b,$c) = @nums; # $a=2 $b=4 $c=6 ($str1,$str2) = ("this", "that"); ($x,@fewer) = @nums; # $x=2 @fewer=(4,6,9) ($t1,$t2,$t3,$t4) = @fewer # $t1=4 $t2=6 $t3=9 $t4 is undef ("this","that") = @dogs; # MAKES NO SENSEAs this demonstrates, perl is very nice about how it makes the assignments. If there are more elements on the right side than on the left the extra are ignored. If there are more on the left than on the right, the extra are assigned the undefined value. And perl will not issue you any warnings. The last example really makes no sense and perl should complain.
A very handy aspect of perl is that you can get the length of the array by assigning the entire array to a single scalar.
$len = @nums; # $len=3 ($len) = @nums # treats the left hand side as a list and # $len=2, the first element of @nums
Being a language that really tries to cover all the bases when it comes to everyday programming, perl has some functions which manipulate arrays.
@dogs=("collie","sheppard","hound","mutt");
pop(@dogs); # @dogs=("collie","sheppard","hound")
shift(@dogs); # @dogs = ("sheppard","hound","bowser")
unshift(@dogs,"queeny"); # @dogs = ("queeny","sheppard","hound","bowser")
Here is a good place to put in a plug for the -w option. This option causes perl to warn you about things which may be legal but like the fourth example above could be potential for erroneous results. When developing the script I recommend that you use the -w but be sure that you take it out of anything that you submit for the labs or actually put into use. The reason for that last is that if you are running the script in the background, spurious output can result in the script being halted because it is not connected to an output device.
%dogs=("black","labrador","red","setter","white","poodle"); $grades{"john"}=45.6; %grades = ("john",45.6,"sarah",90.4); %grades = 45.6 #this causes an errorNote that when referencing a single element of a hash, we use braces {} instead of brackets.
We can also make assignments from hashes to other types but the results may not be what you hope for when dealing with assignments to arrays. That order thing again.
@doggy=%dogs; # @doggy = "black","labrador","red","setter","white","poodle" # or "red","setter","white","poodle","black","labrador" # or "white","poodle", "black","labrador","red","setter" $dog=$dogs{"black"}; # $dog="labrador" $dogs{"black"}="newfoundland";The point with ordering of the assignment from a hash to an array is that it all depends on the keys and how they "hash". The only thing you can depend on is that the key-value pairs will be together. There may come a time when you want just the keys to a hash. Well perl can help you there. There is a function, keys which when given a hash returns a list of the keys, in some arbitrary order. When given an empty hash keys returns an empty list.
@colors=keys(%dogs) # @colors = ("black","white","red") in some # order
Operator | Purpose | Example |
---|---|---|
+ | addition | $a= 3 + 4; #$a = 7 |
- | subtraction | $b= 7 - 3; #$b = 4 |
* | multiplication | $c= 3 * 4; #$c =12 |
/ | floating point division | $d= 10 / 3; #$d = 3.333333... |
% | modulo (always integer) | $e= 10 % 3; #$e = 1 $e= 10.43 % 3.9; #$e = 1 |
** | exponentiation | $f= 5 ** 3; #$f = 125 |
Also available are the normal range of numerical comparisons operators. These operators return 1 if the comparison is true and something which, if coerced to an integer, evaluates as 0 if false;
Operator | Purpose |
---|---|
== | equal |
!= | not equal |
< | less than |
> | greater than |
<= | less than or equal to |
>= | greater than or equal to |
Like C, you cannot do numerical comparisons with strings. If you try, perl will convert the string to some numeric value. Leading whitespace is ignored and trailing non-numeric values are discarded. Thus " 23.928asldf543" becomes 23.928 and "johnson" and "johnson4" become 0. This same thing will happen if you try to use a string any place perl is expecting a numeric value. There is only one operator which corresponds to any of the arithmetic operators and that is "." which concatenates 2 strings. It does not modify either string rather it returns a new string which is the two operands together
$line="This"." is"; # $line = "This is" $line=$line." my country"; # $line = "This is my countryAnd, sensibly, the comparison operators for strings are different from those for numeric values, they are in fact string representations of those other operators.
Operator | Purpose |
---|---|
eq | equal |
ne | not equal |
lt | less than |
gt | greater than |
le | less than or equal to |
ge | greater than or equal to |
This is about as far as I want to go today. We will cover fancy string stuff and give some examples of the things we have and will have covered, a "putting it all together" type thing, next week.