From: Rafael Garcia-Suarez Date: Mon, 25 Jun 2007 09:02:18 +0000 (+0000) Subject: PerlFAQ sync. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ac003c96a6d5a0d39f4ecf8f3491d6a6408e7b47;p=p5sagit%2Fp5-mst-13.2.git PerlFAQ sync. p4raw-id: //depot/perl@31456 --- diff --git a/pod/perlfaq1.pod b/pod/perlfaq1.pod index bb166ef..3167ed2 100644 --- a/pod/perlfaq1.pod +++ b/pod/perlfaq1.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq1 - General Questions About Perl ($Revision: 8539 $) +perlfaq1 - General Questions About Perl ($Revision: 9671 $) =head1 DESCRIPTION @@ -325,7 +325,7 @@ to sign email and usenet messages starting in the late 1980s. He previously used the phrase with many subjects ("Just another x hacker,"), so to distinguish his JAPH, he started to write them as Perl programs: - print "Just another Perl hacker,"; + print "Just another Perl hacker, "; Note the trailing comma and space, which allows the addition of other JAxH clauses for his many other interests. @@ -390,9 +390,9 @@ You might find these links useful: =head1 REVISION -Revision: $Revision: 8539 $ +Revision: $Revision: 9671 $ -Date: $Date: 2007-01-11 00:07:14 +0100 (Thu, 11 Jan 2007) $ +Date: $Date: 2007-06-23 18:38:20 +0200 (Sat, 23 Jun 2007) $ See L for source control details and availability. diff --git a/pod/perlfaq2.pod b/pod/perlfaq2.pod index a276b83..ebb64d1 100644 --- a/pod/perlfaq2.pod +++ b/pod/perlfaq2.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq2 - Obtaining and Learning about Perl ($Revision: 8539 $) +perlfaq2 - Obtaining and Learning about Perl ($Revision: 9462 $) =head1 DESCRIPTION @@ -407,7 +407,8 @@ Recommended books on (or mostly on) Perl follow. I ( http://www.theperlreview.com ) focuses on Perl almost completely (although it sometimes sneaks in an article about -another language). +another language). There's also I<$foo Magazin>, a german magazine +dedicated to Perl, at ( http://www.foo-magazin.de ). Magazines that frequently carry quality articles on Perl include I ( http://www.theperlreview.com ), I ( @@ -520,9 +521,9 @@ the I question earlier in this document. =head1 REVISION -Revision: $Revision: 8539 $ +Revision: $Revision: 9462 $ -Date: $Date: 2007-01-11 00:07:14 +0100 (Thu, 11 Jan 2007) $ +Date: $Date: 2007-04-27 08:24:33 +0200 (Fri, 27 Apr 2007) $ See L for source control details and availability. diff --git a/pod/perlfaq4.pod b/pod/perlfaq4.pod index 25418d0..ff0b0ce 100644 --- a/pod/perlfaq4.pod +++ b/pod/perlfaq4.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq4 - Data Manipulation ($Revision: 8539 $) +perlfaq4 - Data Manipulation ($Revision: 9491 $) =head1 DESCRIPTION @@ -1433,7 +1433,7 @@ that satisfies the condition. In general, you usually don't need a linked list in Perl, since with regular arrays, you can push and pop or shift and unshift at either end, or you can use splice to add and/or remove arbitrary number of -elements at arbitrary points. Both pop and shift are both O(1) +elements at arbitrary points. Both pop and shift are O(1) operations on Perl's dynamic arrays. In the absence of shifts and pops, push in general needs to reallocate on the order every log(N) times, and unshift will need to copy pointers each time. @@ -1615,7 +1615,7 @@ unpublished) of Knuth's I and will work on any list: #!/usr/bin/perl -n - # Fischer-Kause ordered permutation generator + # Fischer-Krause ordered permutation generator sub permute (&@) { my $code = shift; @@ -2260,9 +2260,9 @@ the C module from CPAN instead--it makes number-crunching easy. =head1 REVISION -Revision: $Revision: 8539 $ +Revision: $Revision: 9491 $ -Date: $Date: 2007-01-11 00:07:14 +0100 (Thu, 11 Jan 2007) $ +Date: $Date: 2007-05-02 13:14:13 +0200 (Wed, 02 May 2007) $ See L for source control details and availability. diff --git a/pod/perlfaq5.pod b/pod/perlfaq5.pod index dd11f66..3f1c88e 100644 --- a/pod/perlfaq5.pod +++ b/pod/perlfaq5.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq5 - Files and Formats ($Revision: 8579 $) +perlfaq5 - Files and Formats ($Revision: 9576 $) =head1 DESCRIPTION @@ -1178,9 +1178,9 @@ C function from the C module: POSIX::close( $fd ); -This should rarely be necessary, as the Perl Cclose()> function is to be +This should rarely be necessary, as the Perl C function is to be used for things that Perl opened itself, even if it was a dup of a -numeric descriptor as with MHCONTEXT above. But if you really have +numeric descriptor as with C above. But if you really have to, you may be able to do this: require 'sys/syscall.ph'; @@ -1280,9 +1280,9 @@ If your array contains lines, just print them: =head1 REVISION -Revision: $Revision: 8579 $ +Revision: $Revision: 9576 $ -Date: $Date: 2007-01-14 19:28:09 +0100 (Sun, 14 Jan 2007) $ +Date: $Date: 2007-05-19 18:58:05 +0200 (Sat, 19 May 2007) $ See L for source control details and availability. diff --git a/pod/perlfaq7.pod b/pod/perlfaq7.pod index 9889104..2973681 100644 --- a/pod/perlfaq7.pod +++ b/pod/perlfaq7.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq7 - General Perl Language Issues ($Revision: 9309 $) +perlfaq7 - General Perl Language Issues ($Revision: 9620 $) =head1 DESCRIPTION @@ -22,18 +22,18 @@ and mirrors." They are type specifiers, as detailed in L: - $ for scalar values (number, string or reference) - @ for arrays - % for hashes (associative arrays) - & for subroutines (aka functions, procedures, methods) - * for all types of that symbol name. In version 4 you used them like - pointers, but in modern perls you can just use references. + $ for scalar values (number, string or reference) + @ for arrays + % for hashes (associative arrays) + & for subroutines (aka functions, procedures, methods) + * for all types of that symbol name. In version 4 you used them like + pointers, but in modern perls you can just use references. There are couple of other symbols that you're likely to encounter that aren't really type specifiers: - <> are used for inputting a record from a filehandle. - \ takes a reference to something. + <> are used for inputting a record from a filehandle. + \ takes a reference to something. Note that is I the type specifier for files nor the name of the handle. It is the C<< <> >> operator applied @@ -52,35 +52,36 @@ consisting of a simple word (that isn't the name of a defined subroutine) and the left-hand operand to the C<< => >> operator both count as though they were quoted: - This is like this - ------------ --------------- - $foo{line} $foo{'line'} - bar => stuff 'bar' => stuff + This is like this + ------------ --------------- + $foo{line} $foo{'line'} + bar => stuff 'bar' => stuff The final semicolon in a block is optional, as is the final comma in a list. Good style (see L) says to put them in except for one-liners: - if ($whoops) { exit 1 } - @nums = (1, 2, 3); + if ($whoops) { exit 1 } + @nums = (1, 2, 3); + + if ($whoops) { + exit 1; + } - if ($whoops) { - exit 1; - } - @lines = ( + @lines = ( "There Beren came from mountains cold", "And lost he wandered under leaves", - ); + ); =head2 How do I skip some return values? One way is to treat the return values as a list and index into it: - $dir = (getpwnam($user))[7]; + $dir = (getpwnam($user))[7]; Another way is to use undef as an element on the left-hand-side: - ($dev, $ino, undef, undef, $uid, $gid) = stat($file); + ($dev, $ino, undef, undef, $uid, $gid) = stat($file); You can also use a list slice to select only the elements that you need: @@ -93,10 +94,10 @@ If you are running Perl 5.6.0 or better, the C pragma allows fine control of what warning are produced. See L for more details. - { + { no warnings; # temporarily turn off warnings $a = $b + $c; # I know these might be undef - } + } Additionally, you can enable and disable categories of warnings. You turn off the categories you want to ignore and you can still @@ -111,10 +112,10 @@ complete details, including the category names and hierarchy. If you have an older version of Perl, the C<$^W> variable (documented in L) controls runtime warnings for a block: - { + { local $^W = 0; # temporarily turn off warnings $a = $b + $c; # I know these might be undef - } + } Note that like all the punctuation variables, you cannot currently use my() on C<$^W>, only local(). @@ -135,17 +136,17 @@ L. A common mistake is to write: - unlink $file || die "snafu"; + unlink $file || die "snafu"; This gets interpreted as: - unlink ($file || die "snafu"); + unlink ($file || die "snafu"); To avoid this problem, either put in extra parentheses or use the super low precedence C operator: - (unlink $file) || die "snafu"; - unlink $file or die "snafu"; + (unlink $file) || die "snafu"; + unlink $file or die "snafu"; The "English" operators (C, C, C, and C) deliberately have precedence lower than that of list operators for @@ -160,7 +161,7 @@ Although it has the same precedence as in C, Perl's C operator produces an lvalue. This assigns $x to either $a or $b, depending on the trueness of $maybe: - ($maybe ? $a : $b) = $x; + ($maybe ? $a : $b) = $x; =head2 How do I declare/create a structure? @@ -168,10 +169,10 @@ In general, you don't "declare" a structure. Just use a (probably anonymous) hash reference. See L and L for details. Here's an example: - $person = {}; # new anonymous hash - $person->{AGE} = 24; # set field AGE to 24 - $person->{NAME} = "Nat"; # set field NAME to "Nat" - + $person = {}; # new anonymous hash + $person->{AGE} = 24; # set field AGE to 24 + $person->{NAME} = "Nat"; # set field NAME to "Nat" + If you're looking for something a bit more rigorous, try L. =head2 How do I create a module? @@ -229,12 +230,12 @@ but encourages closures. Here's a classic non-closure function-generating function: - sub add_function_generator { - return sub { shift() + shift() }; - } + sub add_function_generator { + return sub { shift() + shift() }; + } - $add_sub = add_function_generator(); - $sum = $add_sub->(4,5); # $sum is 9 now. + $add_sub = add_function_generator(); + $sum = $add_sub->(4,5); # $sum is 9 now. The anonymous subroutine returned by add_function_generator() isn't technically a closure because it refers to no lexicals outside its own @@ -247,13 +248,13 @@ outside the scope of that function itself. Such a reference requires that Perl return a proper closure, thus locking in for all time the value that the lexical had when the function was created. - sub make_adder { - my $addpiece = shift; - return sub { shift() + $addpiece }; - } - - $f1 = make_adder(20); - $f2 = make_adder(555); + sub make_adder { + my $addpiece = shift; + return sub { shift() + $addpiece }; + } + + $f1 = make_adder(20); + $f2 = make_adder(555); Now C<&$f1($n)> is always 20 plus whatever $n you pass in, whereas C<&$f2($n)> is always 555 plus whatever $n you pass in. The $addpiece @@ -262,8 +263,8 @@ in the closure sticks around. Closures are often used for less esoteric purposes. For example, when you want to pass in a bit of code into a function: - my $line; - timeout( 30, sub { $line = } ); + my $line; + timeout( 30, sub { $line = } ); If the code to execute had been passed in as a string, C<< '$line = ' >>, there would have been no way for the @@ -277,10 +278,10 @@ This is sometimes used with a BEGIN block in package files to make sure a variable doesn't get meddled with during the lifetime of the package: - BEGIN { - my $id = 0; - sub next_id { ++$id } - } + BEGIN { + my $id = 0; + sub next_id { ++$id } + } This is discussed in more detail in L, see the entry on I. @@ -296,12 +297,13 @@ interacting with either closures or aliased foreach() iterator variables and subroutine arguments. It used to be easy to inadvertently lose a variable's value this way, but now it's much harder. Take this code: - my $f = 'foo'; - sub T { - while ($i++ < 3) { my $f = $f; $f .= "bar"; print $f, "\n" } - } - T; - print "Finally $f\n"; + my $f = 'foo'; + sub T { + while ($i++ < 3) { my $f = $f; $f .= "bar"; print $f, "\n" } + } + + T; + print "Finally $f\n"; If you are experiencing variable suicide, that C in the subroutine doesn't pick up a fresh copy of the C<$f> whose value is . The output @@ -338,16 +340,16 @@ passing regular expressions. Regular variables and functions are quite easy to pass: just pass in a reference to an existing or anonymous variable or function: - func( \$some_scalar ); + func( \$some_scalar ); - func( \@some_array ); - func( [ 1 .. 10 ] ); + func( \@some_array ); + func( [ 1 .. 10 ] ); - func( \%some_hash ); - func( { this => 10, that => 20 } ); + func( \%some_hash ); + func( { this => 10, that => 20 } ); - func( \&some_func ); - func( sub { $_[0] ** $_[1] } ); + func( \&some_func ); + func( sub { $_[0] ** $_[1] } ); =item Passing Filehandles @@ -360,7 +362,7 @@ which you treat as any other scalar. sub func { my $passed_fh = shift; - my $line = <$fh>; + my $line = <$passed_fh>; } Before Perl 5.6, you had to use the C<*FH> or C<\*FH> notations. @@ -376,12 +378,12 @@ strings and use an exception-trapping eval, or else be very, very clever. Here's an example of how to pass in a string to be regex compared using C: - sub compare($$) { - my ($val1, $regex) = @_; - my $retval = $val1 =~ /$regex/; + sub compare($$) { + my ($val1, $regex) = @_; + my $retval = $val1 =~ /$regex/; return $retval; - } - $match = compare("old McDonald", qr/d.*D/i); + } + $match = compare("old McDonald", qr/d.*D/i); Notice how C allows flags at the end. That pattern was compiled at compile time, although it was executed later. The nifty C @@ -389,25 +391,25 @@ notation wasn't introduced until the 5.005 release. Before that, you had to approach this problem much less intuitively. For example, here it is again if you don't have C: - sub compare($$) { - my ($val1, $regex) = @_; - my $retval = eval { $val1 =~ /$regex/ }; + sub compare($$) { + my ($val1, $regex) = @_; + my $retval = eval { $val1 =~ /$regex/ }; die if $@; return $retval; - } + } - $match = compare("old McDonald", q/($?i)d.*D/); + $match = compare("old McDonald", q/($?i)d.*D/); Make sure you never say something like this: - return eval "\$val =~ /$regex/"; # WRONG + return eval "\$val =~ /$regex/"; # WRONG or someone can sneak shell escapes into the regex due to the double interpolation of the eval and the double-quoted string. For example: - $pattern_of_evil = 'danger ${ system("rm -rf * &") } danger'; + $pattern_of_evil = 'danger ${ system("rm -rf * &") } danger'; - eval "\$string =~ /$pattern_of_evil/"; + eval "\$string =~ /$pattern_of_evil/"; Those preferring to be very, very clever might see the O'Reilly book, I, by Jeffrey Friedl. Page 273's @@ -418,23 +420,23 @@ citation of this book is given in L. To pass an object method into a subroutine, you can do this: - call_a_lot(10, $some_obj, "methname") - sub call_a_lot { - my ($count, $widget, $trick) = @_; - for (my $i = 0; $i < $count; $i++) { - $widget->$trick(); - } - } + call_a_lot(10, $some_obj, "methname") + sub call_a_lot { + my ($count, $widget, $trick) = @_; + for (my $i = 0; $i < $count; $i++) { + $widget->$trick(); + } + } Or, you can use a closure to bundle up the object, its method call, and arguments: - my $whatnot = sub { $some_obj->obfuscate(@args) }; - func($whatnot); - sub func { - my $code = shift; - &$code(); - } + my $whatnot = sub { $some_obj->obfuscate(@args) }; + func($whatnot); + sub func { + my $code = shift; + &$code(); + } You could also investigate the can() method in the UNIVERSAL class (part of the standard perl distribution). @@ -463,16 +465,16 @@ can access the value (and each time you do, you increment the value). The data in chunk of memory defined by C<$count> is private to C. - BEGIN { - my $count = 1; - sub counter { $count++ } - } - - my $start = counter(); - - .... # code that calls counter(); - - my $end = counter(); + BEGIN { + my $count = 1; + sub counter { $count++ } + } + + my $start = counter(); + + .... # code that calls counter(); + + my $end = counter(); In the previous example, you created a function-private variable because only one function remembered its reference. You could define @@ -485,11 +487,11 @@ function adds to the value and the other simply returns the value. They can both access C<$count>, and since it has gone out of scope, there is no other way to access it. - BEGIN { - my $count = 1; - sub increment_count { $count++ } - sub return_count { $count } - } + BEGIN { + my $count = 1; + sub increment_count { $count++ } + sub return_count { $count } + } To declare a file-private variable, you still use a lexical variable. A file is also a scope, so a lexical variable defined in the file @@ -515,25 +517,25 @@ lexical variables or (improperly) static(ly scoped) variables. For instance: - sub visible { - print "var has value $var\n"; - } - - sub dynamic { - local $var = 'local'; # new temporary value for the still-global - visible(); # variable called $var - } - - sub lexical { - my $var = 'private'; # new private variable, $var - visible(); # (invisible outside of sub scope) - } - - $var = 'global'; - - visible(); # prints global - dynamic(); # prints local - lexical(); # prints global + sub visible { + print "var has value $var\n"; + } + + sub dynamic { + local $var = 'local'; # new temporary value for the still-global + visible(); # variable called $var + } + + sub lexical { + my $var = 'private'; # new private variable, $var + visible(); # (invisible outside of sub scope) + } + + $var = 'global'; + + visible(); # prints global + dynamic(); # prints local + lexical(); # prints global Notice how at no point does the value "private" get printed. That's because $var only has that value within the block of the lexical() @@ -572,8 +574,8 @@ dynamic variable into the current lexical scope. print "lexical is $var\n"; { - our $var; - print "global is $var\n"; + our $var; + print "global is $var\n"; } =head2 What's the difference between deep and shallow binding? @@ -601,15 +603,15 @@ doesn't help you (such as with sort()). To enforce scalar context in this particular case, however, you need merely omit the parentheses: - local($foo) = ; # WRONG - local($foo) = scalar(); # ok - local $foo = ; # right + local($foo) = ; # WRONG + local($foo) = scalar(); # ok + local $foo = ; # right You should probably be using lexical variables anyway, although the issue is the same here: - my($foo) = ; # WRONG - my $foo = ; # right + my($foo) = ; # WRONG + my $foo = ; # right =head2 How do I redefine a builtin function, operator, or method? @@ -650,12 +652,12 @@ where they don't belong. If one wants to use pure Perl and to be compatible with Perl versions prior to 5.10, the general answer is to write a construct like this: - for ($variable_to_test) { - if (/pat1/) { } # do something - elsif (/pat2/) { } # do something else - elsif (/pat3/) { } # do something else - else { } # default - } + for ($variable_to_test) { + if (/pat1/) { } # do something + elsif (/pat2/) { } # do something else + elsif (/pat3/) { } # do something else + else { } # default + } Here's a simple example of a switch based on pattern matching, lined up in a way to make it look more like a switch statement. @@ -702,29 +704,29 @@ different characters or if you want to arrange the matches so that one takes precedence over another, as C<"SEND"> has precedence over C<"STOP"> here: - chomp($answer = <>); - if ("SEND" =~ /^\Q$answer/i) { print "Action is send\n" } - elsif ("STOP" =~ /^\Q$answer/i) { print "Action is stop\n" } - elsif ("ABORT" =~ /^\Q$answer/i) { print "Action is abort\n" } - elsif ("LIST" =~ /^\Q$answer/i) { print "Action is list\n" } - elsif ("EDIT" =~ /^\Q$answer/i) { print "Action is edit\n" } + chomp($answer = <>); + if ("SEND" =~ /^\Q$answer/i) { print "Action is send\n" } + elsif ("STOP" =~ /^\Q$answer/i) { print "Action is stop\n" } + elsif ("ABORT" =~ /^\Q$answer/i) { print "Action is abort\n" } + elsif ("LIST" =~ /^\Q$answer/i) { print "Action is list\n" } + elsif ("EDIT" =~ /^\Q$answer/i) { print "Action is edit\n" } A totally different approach is to create a hash of function references. - my %commands = ( - "happy" => \&joy, - "sad", => \&sullen, - "done" => sub { die "See ya!" }, - "mad" => \&angry, - ); - - print "How are you? "; - chomp($string = ); - if ($commands{$string}) { - $commands{$string}->(); - } else { - print "No such command: $string\n"; - } + my %commands = ( + "happy" => \&joy, + "sad", => \&sullen, + "done" => sub { die "See ya!" }, + "mad" => \&angry, + ); + + print "How are you? "; + chomp($string = ); + if ($commands{$string}) { + $commands{$string}->(); + } else { + print "No such command: $string\n"; + } Note that starting from version 5.10, Perl has now a native switch statement. See L. @@ -771,17 +773,17 @@ the perils of indirect objects in L. If you're just a random program, you can do this to find out what the currently compiled package is: - my $packname = __PACKAGE__; + my $packname = __PACKAGE__; But, if you're a method and you want to print an error message that includes the kind of object you were called on (which is not necessarily the same as the one in which you were compiled): - sub amethod { - my $self = shift; - my $class = ref($self) || $self; - warn "called me from a $class object"; - } + sub amethod { + my $self = shift; + my $class = ref($self) || $self; + warn "called me from a $class object"; + } =head2 How can I comment out a large block of perl code? @@ -791,20 +793,20 @@ for a specific formatter. Use the C format, which no formatter should claim to understand (by policy). Mark the end of the block with <=end>. - # program is here - - =begin comment - - all of this stuff - - here will be ignored - by everyone - + # program is here + + =begin comment + + all of this stuff + + here will be ignored + by everyone + =end comment - - =cut - - # program continues + + =cut + + # program continues The pod directives cannot go just anywhere. You must put a pod directive where the parser is expecting a new statement, @@ -817,23 +819,23 @@ See L for more details. Use this code, provided by Mark-Jason Dominus: - sub scrub_package { - no strict 'refs'; - my $pack = shift; - die "Shouldn't delete main package" - if $pack eq "" || $pack eq "main"; - my $stash = *{$pack . '::'}{HASH}; - my $name; - foreach $name (keys %$stash) { - my $fullname = $pack . '::' . $name; - # Get rid of everything with that name. - undef $$fullname; - undef @$fullname; - undef %$fullname; - undef &$fullname; - undef *$fullname; + sub scrub_package { + no strict 'refs'; + my $pack = shift; + die "Shouldn't delete main package" + if $pack eq "" || $pack eq "main"; + my $stash = *{$pack . '::'}{HASH}; + my $name; + foreach $name (keys %$stash) { + my $fullname = $pack . '::' . $name; + # Get rid of everything with that name. + undef $$fullname; + undef @$fullname; + undef %$fullname; + undef &$fullname; + undef *$fullname; + } } - } Or, if you're using a recent release of Perl, you can just use the Symbol::delete_package() function instead. @@ -843,9 +845,9 @@ just use the Symbol::delete_package() function instead. Beginners often think they want to have a variable contain the name of a variable. - $fred = 23; - $varname = "fred"; - ++$$varname; # $fred now 24 + $fred = 23; + $varname = "fred"; + ++$$varname; # $fred now 24 This works I, but it is a very bad idea for two reasons. @@ -867,9 +869,9 @@ symbolic references, you are just using the package's symbol-table hash (like C<%main::>) instead of a user-defined hash. The solution is to use your own hash or a real reference instead. - $USER_VARS{"fred"} = 23; - $varname = "fred"; - $USER_VARS{$varname}++; # not $$varname++ + $USER_VARS{"fred"} = 23; + $varname = "fred"; + $USER_VARS{$varname}++; # not $$varname++ There we're using the %USER_VARS hash instead of symbolic references. Sometimes this comes up in reading strings from the user with variable @@ -879,20 +881,20 @@ program-addressable namespace and the user-addressable one. Instead of reading a string and expanding it to the actual contents of your program's own variables: - $str = 'this has a $fred and $barney in it'; - $str =~ s/(\$\w+)/$1/eeg; # need double eval + $str = 'this has a $fred and $barney in it'; + $str =~ s/(\$\w+)/$1/eeg; # need double eval it would be better to keep a hash around like %USER_VARS and have variable references actually refer to entries in that hash: - $str =~ s/\$(\w+)/$USER_VARS{$1}/g; # no /e here at all + $str =~ s/\$(\w+)/$USER_VARS{$1}/g; # no /e here at all That's faster, cleaner, and safer than the previous approach. Of course, you don't need to use a dollar sign. You could use your own scheme to make it less confusing, like bracketed percent symbols, etc. - $str = 'this has a %fred% and %barney% in it'; - $str =~ s/%(\w+)%/$USER_VARS{$1}/g; # no /e here at all + $str = 'this has a %fred% and %barney% in it'; + $str =~ s/%(\w+)%/$USER_VARS{$1}/g; # no /e here at all Another reason that folks sometimes think they want a variable to contain the name of a variable is because they don't know how to build @@ -900,17 +902,17 @@ proper data structures using hashes. For example, let's say they wanted two hashes in their program: %fred and %barney, and that they wanted to use another scalar variable to refer to those by name. - $name = "fred"; - $$name{WIFE} = "wilma"; # set %fred + $name = "fred"; + $$name{WIFE} = "wilma"; # set %fred - $name = "barney"; - $$name{WIFE} = "betty"; # set %barney + $name = "barney"; + $$name{WIFE} = "betty"; # set %barney This is still a symbolic reference, and is still saddled with the problems enumerated above. It would be far better to write: - $folks{"fred"}{WIFE} = "wilma"; - $folks{"barney"}{WIFE} = "betty"; + $folks{"fred"}{WIFE} = "wilma"; + $folks{"barney"}{WIFE} = "betty"; And just use a multilevel hash to start with. @@ -923,11 +925,11 @@ through the symbol table for resolution. In those cases, you would turn off C temporarily so you can play around with the symbol table. For example: - @colors = qw(red blue green yellow orange purple violet); - for my $name (@colors) { - no strict 'refs'; # renege for the block - *$name = sub { "@_" }; - } + @colors = qw(red blue green yellow orange purple violet); + for my $name (@colors) { + no strict 'refs'; # renege for the block + *$name = sub { "@_" }; + } All those functions (red(), blue(), green(), etc.) appear to be separate, but the real code in the closure actually was compiled only once. @@ -970,9 +972,9 @@ where you expect it so you need to adjust your shebang line. =head1 REVISION -Revision: $Revision: 9309 $ +Revision: $Revision: 9620 $ -Date: $Date: 2007-03-23 15:28:16 +0100 (Fri, 23 Mar 2007) $ +Date: $Date: 2007-05-29 19:57:58 +0200 (Tue, 29 May 2007) $ See L for source control details and availability. diff --git a/pod/perlfaq8.pod b/pod/perlfaq8.pod index 628e022..d357f1e 100644 --- a/pod/perlfaq8.pod +++ b/pod/perlfaq8.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq8 - System Interaction ($Revision: 8539 $) +perlfaq8 - System Interaction ($Revision: 9667 $) =head1 DESCRIPTION @@ -334,12 +334,11 @@ You spend lots and lots of money on dedicated hardware, but this is bound to get you talked about. Seriously, you can't if they are Unix password files--the Unix -password system employs one-way encryption. It's more like hashing than -encryption. The best you can check is whether something else hashes to -the same string. You can't turn a hash back into the original string. -Programs like Crack -can forcibly (and intelligently) try to guess passwords, but don't -(can't) guarantee quick success. +password system employs one-way encryption. It's more like hashing +than encryption. The best you can do is check whether something else +hashes to the same string. You can't turn a hash back into the +original string. Programs like Crack can forcibly (and intelligently) +try to guess passwords, but don't (can't) guarantee quick success. If you're worried about users selecting bad passwords, you should proactively check when they try to change their password (by modifying @@ -818,8 +817,8 @@ like this: @ok = `grep @opts '$search_string' @filenames`; -As of Perl 5.8.0, you can use open() with multiple arguments. -Just like the list forms of system() and exec(), no shell +As of Perl 5.8.0, you can use C with multiple arguments. +Just like the list forms of C and C, no shell escapes happen. open( GREP, "-|", 'grep', @opts, $search_string, @filenames ); @@ -833,18 +832,19 @@ You can also: while () { chomp; push(@ok, $_); - } - close GREP; + } + close GREP; } else { exec 'grep', @opts, $search_string, @filenames; } -Just as with system(), no shell escapes happen when you exec() a list. -Further examples of this can be found in L. +Just as with C, no shell escapes happen when you C a +list. Further examples of this can be found in L. -Note that if you're use Microsoft, no solution to this vexing issue -is even possible. Even if Perl were to emulate fork(), you'd still -be stuck, because Microsoft does not have a argc/argv-style API. +Note that if you're using Windows, no solution to this vexing issue is +even possible. Even if Perl were to emulate C, you'd still be +stuck, because Windows does not have an argc/argv-style API. =head2 Why can't my script read from STDIN after I gave it EOF (^D on Unix, ^Z on MS-DOS)? @@ -1073,7 +1073,7 @@ sysopen(): =head2 How do I tell the difference between errors from the shell and perl? -(answer contributed by brian d foy, C<< >> +(answer contributed by brian d foy) When you run a Perl script, something else is running the script for you, and that something else may output error messages. The script might @@ -1211,42 +1211,101 @@ In general, you usually want C and a proper Perl module. =head2 How do I keep my own module/library directory? -When you build modules, use the PREFIX and LIB options when generating -Makefiles: +When you build modules, tell Perl where to install the modules. + +For C-based distributions, use the PREFIX and LIB options +when generating Makefiles: perl Makefile.PL PREFIX=/mydir/perl LIB=/mydir/perl/lib -then either set the PERL5LIB environment variable before you run -scripts that use the modules/libraries (see L) or say +You can set this in your CPAN.pm configuration so modules automatically install +in your private library directory when you use the CPAN.pm shell: - use lib '/mydir/perl/lib'; + % cpan + cpan> o conf makepl_arg PREFIX=/mydir/perl,LIB=/mydir/perl/lib + cpan> o conf commit -This is almost the same as +For C-based distributions, use the --install_base option: - BEGIN { - unshift(@INC, '/mydir/perl/lib'); - } + perl Build.PL --install_base /mydir/perl + +You can configure CPAN.pm to automatically use this option too: -except that the lib module checks for machine-dependent subdirectories. -See Perl's L for more information. + % cpan + cpan> o conf mbuild_arg --install_base /mydir/perl + cpan> o conf commit =head2 How do I add the directory my program lives in to the module/library search path? +(contributed by brian d foy) + +If you know the directory already, you can add it to C<@INC> as you would +for any other directory. You might if you know the directory +at compile time: + + use lib $directory; + +The trick in this task is to find the directory. Before your script does +anything else (such as a C), you can get the current working +directory with the C module, which comes with Perl: + + BEGIN { + use Cwd; + our $directory = cwd; + } + + use lib $directory; + +You can do a similar thing with the value of C<$0>, which holds the +script name. That might hold a relative path, but C can turn +it into an absolute path. Once you have the + + BEGIN { + use File::Spec::Functions qw(rel2abs); + use File::Basename qw(dirname); + + my $path = rel2abs( $0 ); + our $directory = dirname( $path ); + } + + use lib $directory; + +The C module, which comes with Perl, might work. It searches +through C<$ENV{PATH}> (so your script has to be in one of those +directories). You can then use that directory (in C<$FindBin::Bin>) +to locate nearby directories you want to add: + use FindBin; - use lib "$FindBin::Bin"; - use your_own_modules; + use lib "$FindBin::Bin/../lib"; =head2 How do I add a directory to my include path (@INC) at runtime? -Here are the suggested ways of modifying your include path: +Here are the suggested ways of modifying your include path, including +environment variables, run-time switches, and in-code statements: + +=over 4 + +=item the PERLLIB environment variable + + $ export PERLLIB=/path/to/my/dir + $ perl program.pl + +=item the PERL5LIB environment variable - the PERLLIB environment variable - the PERL5LIB environment variable - the perl -Idir command line flag - the use lib pragma, as in - use lib "$ENV{HOME}/myown_perllib"; + $ export PERL5LIB=/path/to/my/dir + $ perl program.pl + +=item the perl -Idir command line flag + + $ perl -I/path/to/my/dir program.pl + +=item the use lib pragma: + + use lib "$ENV{HOME}/myown_perllib"; + +=back -The latter is particularly useful because it knows about machine +The last is particularly useful because it knows about machine dependent architectures. The lib.pm pragmatic module was first included with the 5.002 release of Perl. @@ -1258,9 +1317,9 @@ but other times it is not. Modern programs C instead. =head1 REVISION -Revision: $Revision: 8539 $ +Revision: $Revision: 9667 $ -Date: $Date: 2007-01-11 00:07:14 +0100 (Thu, 11 Jan 2007) $ +Date: $Date: 2007-06-20 06:13:55 +0200 (Wed, 20 Jun 2007) $ See L for source control details and availability.