Comments requested: brief summary of Perl

A

Adam Barr

For a book I am working on, I have written a brief (13 page) summary
of Perl. The intent of this is that an experienced programmer who did
not know Perl would be able to get enough information to read and
understand Perl programs. It is not meant to be a 100% complete
summary of the language, but everything in there should be correct.

If anyone is interested, please feel free to read it and send me
comments. Note that the material is copyrighted, this document is
provided for review only, and the ideas contained in any comments may
be used in the book, in whole or in part, with no rights granted to
the person who provided the comments. I will however acknowledge by
name (if desired) anyone who sends comments.

The information is in PDF form per my publisher's request, but if this
is a problem for anyone, email me and I can send it to you in plain
text.

The file is at

http://www.proudlyserving.com/language/perl.pdf

If you follow other newsgroups (or get comp.lang.perl, where I first
posted this), you may have noticed that I have written similar
summaries for other languages, that I have also posted about.

Thank you.

- Adam Barr
(e-mail address removed)
 
J

John W. Krahn

Adam said:
For a book I am working on, I have written a brief (13 page) summary
of Perl. The intent of this is that an experienced programmer who did
not know Perl would be able to get enough information to read and
understand Perl programs. It is not meant to be a 100% complete
summary of the language, but everything in there should be correct.

If anyone is interested, please feel free to read it and send me
comments. Note that the material is copyrighted, this document is
provided for review only, and the ideas contained in any comments may
be used in the book, in whole or in part, with no rights granted to
the person who provided the comments. I will however acknowledge by
name (if desired) anyone who sends comments.

The information is in PDF form per my publisher's request, but if this
is a problem for anyone, email me and I can send it to you in plain
text.

The file is at

http://www.proudlyserving.com/language/perl.pdf

From page 2:
Strings can be quoted with either single or double quotes. Within single quotes, the only
special characters in a string are the backslash and the single quote; to put an actual backslash in a
single-quoted string you use \\ , and to put a single quote you use \' , as in these examples:

A backslash does not have to be escaped unless it is the last character in the string.

$ perl -le' $_ = q/ab\cd/; print'
ab\cd
$ perl -le' $_ = q/ab\cd\/; print'
Can't find string terminator "/" anywhere before EOF at -e line 1.


From page 3:
The range operator can be used as a shortcut for a list that is a sequence of numbers:

That should be "a sequence of numbers or letters"

$ perl -le' @number1to5 = (1..5); @letterAtoE = ("A".."E"); print "@number1to5 @letterAtoE"'
1 2 3 4 5 A B C D E


From page 4:
Remember that negative indices count back from the end of the list, so @arr[0..-1] is the
whole array.

When you use the range operator in a list context the right-hand number has to be greater
than the left-hand number so [0..-1] won't work. You can use @arr[0..$#arr] for the
whole array.
push ($newelement, @mylist);
unshift (1, 2, 3), @numberlist;

The array has to be the first argument:

push( @mylist, $newelement );
unshift @numberlist, 1, 2, 3;


From page 5:
splice ($listA, -1, 1, "last"); # replace last element
splice ($listB, 1, 2); # remove second and third elements

The first argument of splice has to be an array:

$ perl -le' splice $scalar, 0, 1, "item"; print $scalar'
Type of arg 1 to splice must be array (not scalar dereference) at -e line 1, near ""item";"
Execution of -e aborted due to compilation errors.

The entire contents of a hash are referred to by precending the name with % . The functions
keys() and values() return lists of the keys and values of a hash:

$machinenames = keys %iphash;
$ipaddrs = values %iphash;

Your description is correct however your example uses scalar context which returns the
number of keys/values in the hash.


From page 8:
foreach @mylist {
print $_;
}

That is a syntax error. Parenthesis are required around @mylist.

foreach ( @mylist ) {
print $_;
}


From page 9:
When Perl reads a line out of a file, it includes the newline character ( '\n' ) at the end. Since
it is common to want to remove this, Perl provides a built-in function chomp() whose only
function is to remove the last character from a string if it is \n .

This isn't actually what chomp() does. It removes whatever the $/ variable has been set to
which can be a string of any size.


From page 11:
if ($number =~ /([0-9a-fA-F]+) {
print ("$number is a valid hexadecimal number\n");
}

That is missing the closing delimiter and parenthesis, it should be:

if ($number =~ /([0-9a-fA-F]+)/) {
print ("$number is a valid hexadecimal number\n");
}




John
 
T

Tassilo v. Parseval

Also sprach Adam Barr:
For a book I am working on, I have written a brief (13 page) summary
of Perl. The intent of this is that an experienced programmer who did
not know Perl would be able to get enough information to read and
understand Perl programs. It is not meant to be a 100% complete
summary of the language, but everything in there should be correct.

If anyone is interested, please feel free to read it and send me
comments. Note that the material is copyrighted, this document is
provided for review only, and the ideas contained in any comments may
be used in the book, in whole or in part, with no rights granted to
the person who provided the comments. I will however acknowledge by
name (if desired) anyone who sends comments.

The information is in PDF form per my publisher's request, but if this
is a problem for anyone, email me and I can send it to you in plain
text.

The file is at

http://www.proudlyserving.com/language/perl.pdf

If you follow other newsgroups (or get comp.lang.perl, where I first
posted this), you may have noticed that I have written similar
summaries for other languages, that I have also posted about.

comp.lang.perl doesn't exist contrary to popular belief.

Anyway, some comments not yet done by John:

Page 1:
Perl stores all numbers as floating point; numbers and strings
together are known as "scalars".

The first part is wrong. Perl stores simple integers as integers and
upgrades the variable if necessary. What you probably meant to say: Perl
transforms numbers from floating point to integer and the other way
round if necessary.

The second part is incomplete. References are also scalars. I find the
wording "numbers and strings together" a little misleading. Maybe you
better just write that a scalar variable can only hold one value,
whatever that is.

Page 2:
Perl also does variable interpolation within double-quoted strings, meaning
variables are replaced with their values:

This only applies to scalars and arrays. Hashes are not interpolated.

Naturally, your summary isn't always accurate and sometimes a bit
sloppy (for instance the bits you wrote about lists is - technically
speaking - wrong). But for a crude introduction this is in order.

Maybe you also want to add some notes about the perldocs. Someone
deciding to stick with Perl for a while thus knows where to find more
(and more precise) information.

Tassilo
 
T

Tony Muler

Had a quick view and here are 2 hints free of charge:

1.
The sentence "Variable names start with $" is wrong/incomplete.
I would write the paragraph rather as:
"Variables do not need to be declared ...
Perl stores all numbers ... as "scalars". Scalar variable
names start with $ (mnemonic: looks like the S in scalar)."

2.
"As a shortcut for list of strings you can use qw (the letter q followed
by the letter w)":
Instead of explaining idiots how to type a 'q' and a 'w' I would rather
write:
"As a shortcut for list of strings you can use qw (stands for _q_uoted
_w_ords)". It is shorter and more usefull.


The document looks very complete and very clear.
(I like the way you do NOT explain local vs. my on filehandles ... I
don't really understand that either :)

T.
 
S

Stuart Moore

The if block on page 10 - should be

if (-f $file) {

not

(if -f $file) {

surely?

References to some websites on perl would be useful- saying modules can
be got from cpan for example.

It might be worth stressing what perl is good at - the regexps are a big
strong point, as are the hashes and lists. Regexps are difficult to
summarise well, you've done pretty well there, but might want to look at:

For [^abcd] explain it matches any character except abcd (how you wrote
it doesn't make it clear that it's the ^ that does the magic here)

You don't need a \ before the - in the phone regexp.
Both the phone and the hex regexp possibly ought to have ^ at the start
and $ at the end.


Other stuff:
Might be worth mentioning that print is used to send stuff to files too.

An explanation of use strict and or use warnings might be useful.

In the list stuff I'd look at mentioning "see also push" for the
$array[$#arrayname+1]= $value
bit - actually, surely those should both be array or arrayname?

Stuart
 
T

Tad McClellan

Adam Barr said:
For a book I am working on, I have written a brief (13 page) summary
of Perl. The intent of this is that an experienced programmer who did
not know Perl would be able to get enough information to read and
understand Perl programs.


So at this point I'm thinking to myself:

I'd better see these Big Things when I get to reviewing it:

defaulting to $_ all over the place
while(<FH>) special case (input gets assigned to $_)
package variables vs. lexical variables
list context vs. scalar context
list (data) vs. array (variable)
strict and warnings

Because they are the things that are likely to invoke a "surprise factor"
for folks accustomed to other programming languages.

If anyone is interested, please feel free to read it and send me
comments.


I don't have time to review it right now, maybe tonight, but I
just wanted to throw out The Biggies before I forgot about it. :)
 
A

Adam Barr

Excellent comments, thank you (especially John for actually trying my
broken examples). I constantly get the $ and @ wrong when typing array
names.

I have a question on storage of numbers. It says in the llama book
that Perl always stores numbers as double-precision floating point. Is
this incorrect?


- adam
 
A

Anno Siegel

Adam Barr said:
Excellent comments, thank you (especially John for actually trying my
broken examples). I constantly get the $ and @ wrong when typing array
names.

I have a question on storage of numbers. It says in the llama book
that Perl always stores numbers as double-precision floating point. Is
this incorrect?

That's technically incorrect. Numbers in the native integer range are
internally stored and treated as such. However, since all conversions
happen automatically, you wouldn't know the difference. Maybe the book
is talking about Perl's numeric range, which would be rightly described
as double precision floating point.

Then again, Randal is known for, and stands by, what he calls pedagogical
lies. It may be a deliberate simplification. Cite? Randal?

Anno
 
A

Anno Siegel

Adam Barr said:
Excellent comments, thank you (especially John for actually trying my
broken examples). I constantly get the $ and @ wrong when typing array
names.

I have a question on storage of numbers. It says in the llama book
that Perl always stores numbers as double-precision floating point. Is
this incorrect?

That's technically incorrect. Numbers in the native integer range are
internally stored and treated as such. However, since all conversions
happen automatically, you wouldn't know the difference. Maybe the book
is talking about Perl's numeric range, which would be rightly described
as double precision floating point.

Then again, Randal is known for, and stands by, what he calls pedagogical
(didactic?) lies. It may be a deliberate simplification. Cite? Randal?

Anno
 
R

Randal L. Schwartz

Anno> That's technically incorrect. Numbers in the native integer range are
Anno> internally stored and treated as such. However, since all conversions
Anno> happen automatically, you wouldn't know the difference. Maybe the book
Anno> is talking about Perl's numeric range, which would be rightly described
Anno> as double precision floating point.

Anno> Then again, Randal is known for, and stands by, what he calls pedagogical
Anno> lies. It may be a deliberate simplification. Cite? Randal?

Yes, this was a careful handwaving. We all know there are nice
optimizations, but for all intents and purposes, there's not anything
you can do at a pure Perl level to detect that a scalar doesn't have
the range and precision of a double-precision floating point. And
that's my point.

print "Just another Perl hacker,"
 
G

gnari

From page 11:
if ($number =~ /([0-9a-fA-F]+) {
print ("$number is a valid hexadecimal number\n");
}

That is missing the closing delimiter and parenthesis, it should be:

if ($number =~ /([0-9a-fA-F]+)/) {
print ("$number is a valid hexadecimal number\n");
}

exept that the example should contain anchors, because it
would print
X&!aF+*hhh hhhz is a valid hexadecimal number
given the right $number

gnari
 
A

Adam Barr

Tad McClellan said:
So at this point I'm thinking to myself:

I'd better see these Big Things when I get to reviewing it:

defaulting to $_ all over the place
while(<FH>) special case (input gets assigned to $_)
package variables vs. lexical variables
list context vs. scalar context
list (data) vs. array (variable)
strict and warnings

Because they are the things that are likely to invoke a "surprise factor"
for folks accustomed to other programming languages.




I don't have time to review it right now, maybe tonight, but I
just wanted to throw out The Biggies before I forgot about it. :)

Thanks. I cover most of that list. But the main goal is to allow
someone to read Perl programs (the specific ones in the book, I mean),
not to write them. So strict won't come into play, and the programs
are not big enough to be split into packages.

- adam
 
T

Tassilo v. Parseval

Also sprach Adam Barr:
Thanks. I cover most of that list. But the main goal is to allow
someone to read Perl programs (the specific ones in the book, I mean),
not to write them. So strict won't come into play, and the programs
are not big enough to be split into packages.

That was what I thought when I scanned through the introduction. Some
important things need to be mentioned though. The first Perl script
I ever saw was

print while <>;

and it left me puzzled and didn't even give me an idea what it might be
doing. With "defaulting to $_ all over the place" Tad probably meant to
say that you should mention how $_ is implied and not written
explicitely in certain situations such as the above (where it happens
twice).

Just mention some of the most common idioms such as

sub func {
my $arg = shift;
...
}

Otherwise the reader of a program will have a very hard time figuring
out what a function does.

Tassilo
 
D

Dave Cross

So strict won't come into play,

It probably should, you know :)
and the programs are not big enough to be split into packages.

Maybe not. But you'll still have the main:: package. And you can still use
both package and lexical variables. And you should explain the difference.

Dave...
 
A

Adam Barr

Anno> That's technically incorrect. Numbers in the native integer range are
Anno> internally stored and treated as such. However, since all conversions
Anno> happen automatically, you wouldn't know the difference. Maybe the book
Anno> is talking about Perl's numeric range, which would be rightly described
Anno> as double precision floating point.

Anno> Then again, Randal is known for, and stands by, what he calls pedagogical
Anno> lies. It may be a deliberate simplification. Cite? Randal?

Yes, this was a careful handwaving. We all know there are nice
optimizations, but for all intents and purposes, there's not anything
you can do at a pure Perl level to detect that a scalar doesn't have
the range and precision of a double-precision floating point. And
that's my point.

print "Just another Perl hacker,"


OK, thanks. I'll fudge a bit in what I say to try to avoid a)
confusing Perl beginners and/or b) annoying Perl hackers.

- adam
 
M

Michele Dondi

For a book I am working on, I have written a brief (13 page) summary
of Perl. The intent of this is that an experienced programmer who did
not know Perl would be able to get enough information to read and
understand Perl programs. It is not meant to be a 100% complete
summary of the language, but everything in there should be correct. [snip]
The file is at

http://www.proudlyserving.com/language/perl.pdf

I'm adding here a few cmts of mine, in the hope that they're correct,
and trying to avoid repetitions with what other posters wrote:

| Perl treats all white space, including new lines, as the same. Blocks of code are enclosed
^^^^^^^^^^^

Perl *generally* treats etc.

| between { and }, and statements end with a semi-colon (;).
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

statements *generally must* end etc.

| Comments are marked with a # symbol; anything following that on a line is ignored.
^^^^^^^^^^^^^^^^^^

normally anything following etc.

| Variables names start with $. They do not need to be declared; they can simply be used.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

They do not need to be declared unless

use strict 'vars';

is in use, and hence 'use strict;', which subsumes the former and
should be used really in any nontrivial script along with
'use warnings;': a program that doesn't use these pragmata is most
likely to be a very old one or to sport programming techniques that
are potentially risky in many ways.

[Please note that I tried to take into account the fact that you're
trying to teach others to *read*, not *write* perl programs.]

| Variables that have not been assigned a value will evaluate to the special reserved value undef.
| Perl stores all numbers as floating point; numbers and strings together are known as "scalars".
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^

Perl can be thought of as storing all numbers as floating point.

Numbers and strings are typical examples of scalars.

| In practice, this means that you can almost always treat a number and its string representation
| as the same. When converting a string to a number, only the characters up to the first nonnumeric
| one are evaluated, so "123ABC" evaluates to 123. A variable that is undef will do the
| "right thing" when used in an expression, evaluating to the number 0 or an empty string as
| appropriate.

But under the highly recommended 'use warnings' it may issue a warning
in certain cases. This explains why this *feature* is sometimes
*locally* turned off:

use warnings;
# ...
{
local $_;
no warnings 'uninitialized';
print "<$_>";
}

| © 2004 Adam Barr. All Rights Reserved.
| Assignment is done with the = sign, as seen above, and you can use an assignment statement
| anywhere you would use a variable: the assignment is done first, then the new value of the
| variable is used:
| $x = ($y = 4); # $x will be 4 also

I think this is not clear, I'd express the concept saying: "assignment
returns a value too, exactly the rvalue that was assigned to the
lvalue", or variations thereof.

| Perl uses +, -, *, and / for the basic mathematical operations. % is modulo (numbers are
| truncated to integers first) and ** is the exponentiation operator, for example 2**16. ++ and --
| work as they do in C/C++ and Java. Perl supports binary assignment operators such as +=, -=,
| %=, and even .= and **=:

and even ||= and x= and such exotic beasts...

| Strings can be quoted with either single or double quotes. Within single quotes, the only

I'm not really an expert so this may technically wrong, but I'd say:

Surprising as it may be, in Perl strings are not really be specified
literally, but are the return value of a family of operators the most
common of which can simply take the form of single or double quotes
respectively so that these latter constructs can be thought of as
literal strings at all effects.

"foo\"bar\"foo" eq qq/foo"bar"foo/;

| (we won't use those fancy ones in programs in this book). Perl also does variable
| interpolation within double-quoted strings, meaning variables are replaced with their values:
| $prompt = "Enter your name\n";
| $name = "Sally";
| $reply = "Hello, $name!";

When dealing with interpolation sometimes it turns necessary to
specify variables in the behind-the-scenes-full-blown form:

my $bar='foo';
print "foo${bar}foo";

| The length() function returns the length of a string; substr() is used to return a part of a
| string, and index() to find the index of a match within a string. String positions are 0-based, so

A somewhat exotic feature of Perl's substr(), and one that sometimes
confuses newbies, is that it returns an lvalue.


Hmmm, I don't have much time left, hope to add a few other cmts next
time...


Michele
 
B

Ben Morrow

Michele Dondi said:
I think this is not clear, I'd express the concept saying: "assignment
returns a value too, exactly the rvalue that was assigned to the
lvalue", or variations thereof.

No, it returns the assigned-to lvalue. This is why

(my $x = $y) =~ s/a/b/;

does what it does.

Ben
 
M

Michele Dondi


Some more cmts...

| Perl uses the term list to describe an ordered collection of scalars. An array is a variable that
| contains a list, so the terms "array" and "list" are often thought of as being the same.

But there are some subtle differences between an array and a list, so
that it may be useful to check:

perldoc -q "What is the difference between a list and an array?"

| An entire list is referenced by preceding the name with @. If a list is included in another list,
^^^^^^^^^^^^^^

Ahem! That is an array, see above...

| As a shortcut for lists of strings, you can use qw (the letter q followed by the letter w):
^^^^^^^

Of "words"!

i.e. ('foo bar', 'bar foo') for example is a list of strings, but you
*can't* use qw{} as a shortcut to specify it...

| Access to elements in an array uses 0-based indexing, and supports negative numbers to
| indicate counting back from the end. When indexing into an array, the list name is preceded with
| $, not @, except for certain circumstances which we won't get into:

When accessing a single element of an array by means of its index, the
*array* name is preceded with [...] (with no exception).

| Consistent with being one less than the size of the array, $#arrayname will be –1 for an
| array that has an empty list.

Stylistic note: why not "empty array"?!?

| When a program is invoked, the list @ARGV contains the command-line parameters that were
| passed to it:
| $firstarg = shift @ARGV;
^^^^^^^^^^^

Also in this case, as in many others, Perl tries to provide you with a
simplified syntax by choosing for you suitable defaults in order to
achieve a DWIM effect, so it may be worth mentioning that shift() is
just like shift(@ARGV) outside of the body of a sub. This idiom is
used very frequently in Perl programs.

BTW: somewhere above you said that you would have stuck to the
convention of explicitly using parentheses for functions args. FWIW:
it is MHO that it is much better not to adhere strictly to this
program...

| There can be only one value for a given key; it is replaced if a new value is assigned.
| The entire contents of a hash are referred to by precending the name with %. The functions
| keys() and values() return lists of the keys and values of a hash:
| $machinenames = keys %iphash;
| $ipaddrs = values %iphash;

This is perfectly legal, but I guess you don't want e.g. $machinenames
to hold the number of machines. You want

@machinenames = keys %iphash;
@ipaddrs = values %iphash;

instead!

| Perl supports else and elsif (note the spelling) blocks after if statements:
| if ($command = "sort") {
| do_sort();
| } elsif ($command = "print") {
| do_print();
| } else {
| invalid_command();
| }

I think you want

if ($command eq "sort") {
...
} elsif ($command eq "print") {

| There are also until loops, which execute as long as their test is false (while and until
| are related the same way as if and unless), and also do/while and do/until loops.

There is also [...] a smart mechanism to emulate other languages'
do/while, do/until loops by means of the 'do' "function"/flow control
statement and a special "coordination" with loop modifiers.

Please note:

while (<>) { print }
^^^^ ^

Parentheses are necessary, semicolon is not (although stylistically
recommended);

do { $_ ||= 'foo'; print } while <>;
^^^

Parentheses are not required, semicolon is.

| Perl allows if, unless, while, until, and foreach to be written as "modifiers" to
| expressions, which can be easier to read in some cases:
| $x += 1 unless $x > 100;
| print $_ foreach (1..10);
| This is just a reordering of the traditional way. In particular, the conditional is still evaluated
| before the code is executed, even though it is to the right of it. With foreach written as a
^^^^^^

unless with do BLOCK, as seen above!

| enclosing the handle between < and > and assigning the result to a variable. In scalar context a

^^^^^^^^^^^^^^
| file handle returns the next line of a file, or undef when end-of-file is reached; in scalar context it

^^^^^^^^^^^^^^
| returns every line of the file. Thus, you can loop through a file either with:

(In addition to what others pointed out...) Ahem!!

| foreach (<STDIN>) { # list context
| process($_);
| }

Now that I come to think of it, and OT WRT this context, it may be
worth mentioning that foreach is just an alias to for...


Well, time to go once again... seeya next time!!


Michele
 
M

Michele Dondi


Some more cmts...

[about REs]
| () can be used to group parts of a regular expression
^^^

But does a lot more than that, with side-effects. For simple grouping
you can use (?: ... ) instead.

| if ($phone =~ /\d{3}\-\d{4}/) {

if ($phone =~ /\d{3}-\d{4}/) {

| The return statement is actually optional; if it is missing, then the subroutine will return the
| value of the last expression calculated, or undef if no expressions were calculated.

But it becomes necessary if one wants to exit early from a sub, as is
often the case e.g. with recursive ones...

| Variables local to a function can be declared with the my operator, so the previous function
| could be written:

Variables local to "anything"! As you should have clearly stated much
above...

| accesses the global variable by name. And, for reasons which are best left to Perl wizards to
| explain, you can't use my on a file handle, you have to use local.

But with recent enough perls it is much better and highly recommended
to use lexical filehandles (unless backwards compatibility is an
issue), as you may explain in the section about open():

my $all = do {
open my $fh, '<', $file or die $!;
local $/;
<$fh> };


Hmmm, seems like eventually I finished it! These are more or less the
cmts and suggestion I felt like giving about your work. Other posters
(Hey, Ben!!) may correct me if, as is unfortunately usual, further
imprecisions have inadvertently slipped in...


Michele
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top