X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlfaq7.pod;h=54e91bda9ba7c37f9ec911c881bf4b60ab5e687a;hb=a537debe17982e491ffa12d12441cf74a452acb2;hp=008f433124daeaee4d2da991a2a07c8cafd7ef05;hpb=f05bbc4047b4e519eb0edbaf2fce2004f4838d1a;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlfaq7.pod b/pod/perlfaq7.pod index 008f433..54e91bd 100644 --- a/pod/perlfaq7.pod +++ b/pod/perlfaq7.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq7 - General Perl Language Issues ($Revision: 1.8 $, $Date: 2002/03/26 15:48:32 $) +perlfaq7 - General Perl Language Issues ($Revision: 1.18 $, $Date: 2004/11/03 22:54:08 $) =head1 DESCRIPTION @@ -38,7 +38,7 @@ really type specifiers: Note that is I the type specifier for files nor the name of the handle. It is the C<< <> >> operator applied to the handle FILE. It reads one line (well, record--see -L) from the handle FILE in scalar context, or I lines +L>) from the handle FILE in scalar context, or I lines in list context. When performing open, close, or any other operation besides C<< <> >> on files, or even when talking about the handle, do I use the brackets. These are correct: C, C pragma @@ -92,6 +97,16 @@ 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 +get other categories of warnings. See L for the +complete details, including the category names and hierarchy. + + { + no warnings 'uninitialized'; + $a = $b + $c; + } If you have an older version of Perl, the C<$^W> variable (documented in L) controls runtime warnings for a block: @@ -208,7 +223,7 @@ but encourages closures. Here's a classic function-generating function: sub add_function_generator { - return sub { shift + shift }; + return sub { shift() + shift() }; } $add_sub = add_function_generator(); @@ -227,7 +242,7 @@ value that the lexical had when the function was created. sub make_adder { my $addpiece = shift; - return sub { shift + $addpiece }; + return sub { shift() + $addpiece }; } $f1 = make_adder(20); @@ -298,37 +313,21 @@ reference to an existing or anonymous variable or function: =item Passing Filehandles -To pass filehandles to subroutines, use the C<*FH> or C<\*FH> notations. -These are "typeglobs"--see L -and especially L for more information. +As of Perl 5.6, you can represent filehandles with scalar variables +which you treat as any other scalar. -Here's an excerpt: + open my $fh, $filename or die "Cannot open $filename! $!"; + func( $fh ); -If you're passing around filehandles, you could usually just use the bare -typeglob, like *STDOUT, but typeglobs references would be better because -they'll still work properly under C. For example: + sub func { + my $passed_fh = shift; - splutter(\*STDOUT); - sub splutter { - my $fh = shift; - print $fh "her um well a hmmm\n"; - } + my $line = <$fh>; + } - $rec = get_rec(\*STDIN); - sub get_rec { - my $fh = shift; - return scalar <$fh>; - } - -If you're planning on generating new filehandles, you could do this: - - sub openit { - my $path = shift; - local *FH; - return open (FH, $path) ? *FH : undef; - } - $fh = openit('< /etc/motd'); - print <$fh>; +Before Perl 5.6, you had to use the C<*FH> or C<\*FH> notations. +These are "typeglobs"--see L +and especially L for more information. =item Passing Regexes @@ -486,28 +485,38 @@ In summary, local() doesn't make what you think of as private, local variables. It gives a global variable a temporary value. my() is what you're looking for if you want private variables. -See L and +See L and L for excruciating details. =head2 How can I access a dynamic variable while a similarly named lexical is in scope? -You can do this via symbolic references, provided you haven't set -C. So instead of $var, use C<${'var'}>. +If you know your package, you can just mention it explicitly, as in +$Some_Pack::var. Note that the notation $::var is B the dynamic $var +in the current package, but rather the one in the "main" package, as +though you had written $main::var. - local $var = "global"; - my $var = "lexical"; + use vars '$var'; + local $var = "global"; + my $var = "lexical"; - print "lexical is $var\n"; + print "lexical is $var\n"; + print "global is $main::var\n"; - no strict 'refs'; - print "global is ${'var'}\n"; +Alternatively you can use the compiler directive our() to bring a +dynamic variable into the current lexical scope. -If you know your package, you can just mention it explicitly, as in -$Some_Pack::var. Note that the notation $::var is I the dynamic -$var in the current package, but rather the one in the C
-package, as though you had written $main::var. Specifying the package -directly makes you hard-code its name, but it executes faster and -avoids running afoul of C. + require 5.006; # our() did not exist before 5.6 + use vars '$var'; + + local $var = "global"; + my $var = "lexical"; + + print "lexical is $var\n"; + + { + our $var; + print "global is $var\n"; + } =head2 What's the difference between deep and shallow binding? @@ -520,7 +529,7 @@ However, dynamic variables (aka global, local, or package variables) are effectively shallowly bound. Consider this just one more reason not to use them. See the answer to L<"What's a closure?">. -=head2 Why doesn't "my($foo) = ;" work right? +=head2 Why doesn't "my($foo) = EFILEE;" work right? C and C give list context to the right hand side of C<=>. The read operation, like so many of Perl's @@ -604,7 +613,7 @@ construct like this: elsif (/pat2/) { } # do something else elsif (/pat3/) { } # do something else else { } # default - } + } Here's a simple example of a switch based on pattern matching, this time lined up in a way to make it look more like a switch statement. @@ -641,7 +650,7 @@ in $whatchamacallit: } -See C for many other +See C for many other examples in this style. Sometimes you should change the positions of the constant and the variable. @@ -659,7 +668,7 @@ C<"STOP"> here: 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. +A totally different approach is to create a hash of function references. my %commands = ( "happy" => \&joy, @@ -674,33 +683,18 @@ A totally different approach is to create a hash of function references. $commands{$string}->(); } else { print "No such command: $string\n"; - } + } -=head2 How can I catch accesses to undefined variables/functions/methods? +=head2 How can I catch accesses to undefined variables, functions, or methods? The AUTOLOAD method, discussed in L and L, lets you capture calls to undefined functions and methods. When it comes to undefined variables that would trigger a warning -under C<-w>, you can use a handler to trap the pseudo-signal -C<__WARN__> like this: - - $SIG{__WARN__} = sub { +under C, you can promote the warning to an error. - for ( $_[0] ) { # voici un switch statement - - /Use of uninitialized value/ && do { - # promote warning to a fatal - die $_; - }; - - # other warning cases to catch could go here; - - warn $_; - } - - }; + use warnings FATAL => qw(uninitialized); =head2 Why can't a method included in this same file be found? @@ -741,32 +735,27 @@ not necessarily the same as the one in which you were compiled): =head2 How can I comment out a large block of perl code? -You can use embedded POD to discard it. The =for directive -lasts until the next paragraph (two consecutive newlines). +You can use embedded POD to discard it. Enclose the blocks you want +to comment out in POD markers, for example C<=for nobody> and C<=cut> +(which marks ends of POD blocks). # program is here =for nobody - This paragraph is commented out - - # program continues - -The =begin and =end directives can contain multiple -paragraphs. - - =begin comment text all of this stuff here will be ignored by everyone - =end comment text + =cut + + # program continues The pod directives cannot go just anywhere. You must put a pod directive where the parser is expecting a new statement, not just in the middle of an expression or some other -arbitrary s grammar production. +arbitrary grammar production. See L for more details. @@ -777,7 +766,7 @@ Use this code, provided by Mark-Jason Dominus: sub scrub_package { no strict 'refs'; my $pack = shift; - die "Shouldn't delete main package" + die "Shouldn't delete main package" if $pack eq "" || $pack eq "main"; my $stash = *{$pack . '::'}{HASH}; my $name; @@ -792,7 +781,7 @@ Use this code, provided by Mark-Jason Dominus: } } -Or, if you're using a recent release of Perl, you can +Or, if you're using a recent release of Perl, you can just use the Symbol::delete_package() function instead. =head2 How can I use a variable as a variable name? @@ -824,7 +813,7 @@ 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. - $fred = 23; + $USER_VARS{"fred"} = 23; $varname = "fred"; $USER_VARS{$varname}++; # not $$varname++ @@ -860,7 +849,7 @@ wanted to use another scalar variable to refer to those by name. $name = "fred"; $$name{WIFE} = "wilma"; # set %fred - $name = "barney"; + $name = "barney"; $$name{WIFE} = "betty"; # set %barney This is still a symbolic reference, and is still saddled with the @@ -884,7 +873,7 @@ can play around with the symbol table. For example: 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. @@ -895,6 +884,31 @@ subroutines, because they are always global--you can't use my() on them. For scalars, arrays, and hashes, though--and usually for subroutines-- you probably only want to use hard references. +=head2 What does "bad interpreter" mean? + +The "bad interpreter" message comes from the shell, not perl. The +actual message may vary depending on your platform, shell, and locale +settings. + +If you see "bad interpreter - no such file or directory", the first +line in your perl script (the "shebang" line) does not contain the +right path to perl (or any other program capable of running scripts). +Sometimes this happens when you move the script from one machine to +another and each machine has a different path to perl---/usr/bin/perl +versus /usr/local/bin/perl for instance. + +If you see "bad interpreter: Permission denied", you need to make your +script executable. + +In either case, you should still be able to run the scripts with perl +explicitly: + + % perl script.pl + +If you get a message like "perl: command not found", perl is not in +your PATH, which might also mean that the location of perl is not +where you expect it so you need to adjust your shebang line. + =head1 AUTHOR AND COPYRIGHT Copyright (c) 1997-2002 Tom Christiansen and Nathan Torkington.