Yes, Perl has a lot of functions. I'm not going to list them here, because the fastest way to find out about them is to read through the function section of Programming Perl or the perlfunc (1) manpage and look at anything you don't recognize that sounds interesting. Here are a few of the more interesting ones.
The grep
function selects elements from its argument list, based upon the result of an expression that's repeatedly evaluated for its truth value, with the $_
variable successively set to each element in the list:
@bigpowers = grep $_ > 6, 1, 2, 4, 8, 16; # gets (8, 16) @b_names = grep /^b/, qw(fred barney betty wilma); @textfiles = grep -T, <*>;
The map
function is similar, but instead of selecting or rejecting items, it merely collects the results of the expression (evaluated in a list context):
@more = map $_ + 3, 3, 5, 7; # gets 6, 8, 10 @squares = map $_ * $_, 1..10; # first 10 squares @that = map "$_\n", @this; # like "unchomp" @triangle = map 1..$_, 1..5; # 1,1,2,1,2,3,1,2,3,4,1,2,3,4,5 %sizes = map { $_, -s } <*>; # hash of files and sizes
Yes, you can construct a piece of code at run-time and then eval
it, just as you can do with the shell. It's actually rather useful, because you can get some compiletime optimizations (like a compiled regular expression) at run-time. You can also use it to trap otherwise fatal errors in a section of code: a fatal error inside the eval
merely exits the eval
and gives you an error status.
For example, here's a program that reads a line of Perl code from the user and then executes it as if it were part of the Perl program:
print "code line: "; chop($code = <STDIN>); eval $code; die "eval: $@" if $@;
You can put Perl code inside the replacement string of a substitute operator with the e
flag. This is handy if you want to construct something complicated for the replacement string, such as calling a subroutine that returns the results of a database lookup. Here's a loop that increments the value of the first column of a series of lines:
while (<>) { s/^(\S+)/$1+1/e; # $1+1 is Perl code, not a string print; }
Another use of eval
is as an exception-handling mechanism:
eval { some_hairy_routine_that_might_die(@args); }; if ($@) { print "oops... some_hairy died with $@"; }
Here, $@
will be empty as long as the eval block worked OK but will have the text of the die message if not.
Of these three constructs (eval "string"
, eval
{
BLOCK
}
, and s///e
) only the first is really what you would think of as an eval
from a shell-programming language. The other two are compiled at compile-time, and incur little additional performance penalty.