This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Generate the warnings masks programatically.
[perl5.git] / pod / perlfaq4.pod
index 6fb4d37..3200e7a 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq4 - Data Manipulation ($Revision: 8539 $)
+perlfaq4 - Data Manipulation ($Revision: 10394 $)
 
 =head1 DESCRIPTION
 
@@ -1006,12 +1006,15 @@ C<Text::Metaphone>, and C<Text::DoubleMetaphone> modules.
 (contributed by brian d foy)
 
 If you can avoid it, don't, or if you can use a templating system,
-such as C<Text::Template> or C<Template> Toolkit, do that instead.
+such as C<Text::Template> or C<Template> Toolkit, do that instead. You
+might even be able to get the job done with C<sprintf> or C<printf>:
+
+       my $string = sprintf 'Say hello to %s and %s', $foo, $bar;
 
 However, for the one-off simple case where I don't want to pull out a
 full templating system, I'll use a string that has two Perl scalar
 variables in it. In this example, I want to expand C<$foo> and C<$bar>
-to their variable's values.
+to their variable's values:
 
        my $foo = 'Fred';
        my $bar = 'Barney';
@@ -1021,17 +1024,22 @@ One way I can do this involves the substitution operator and a double
 C</e> flag.  The first C</e> evaluates C<$1> on the replacement side and
 turns it into C<$foo>. The second /e starts with C<$foo> and replaces
 it with its value. C<$foo>, then, turns into 'Fred', and that's finally
-what's left in the string.
+what's left in the string:
 
        $string =~ s/(\$\w+)/$1/eeg; # 'Say hello to Fred and Barney'
 
 The C</e> will also silently ignore violations of strict, replacing
-undefined variable names with the empty string.
-
-I could also pull the values from a hash instead of evaluating 
-variable names. Using a single C</e>, I can check the hash to ensure
-the value exists, and if it doesn't, I can replace the missing value
-with a marker, in this case C<???> to signal that I missed something:
+undefined variable names with the empty string. Since I'm using the
+C</e> flag (twice even!), I have all of the same security problems I 
+have with C<eval> in its string form. If there's something odd in
+C<$foo>, perhaps something like C<@{[ system "rm -rf /" ]}>, then
+I could get myself in trouble.
+
+To get around the security problem, I could also pull the values from
+a hash instead of evaluating variable names. Using a single C</e>, I
+can check the hash to ensure the value exists, and if it doesn't, I
+can replace the missing value with a marker, in this case C<???> to
+signal that I missed something:
 
        my $string = 'This has $foo and $bar';
        
@@ -1308,7 +1316,7 @@ multiple values against the same array.
 
 If you are testing only once, the standard module C<List::Util> exports
 the function C<first> for this purpose.  It works by stopping once it
-finds the element. It's written in C for speed, and its Perl equivalant
+finds the element. It's written in C for speed, and its Perl equivalent
 looks like this subroutine:
 
        sub first (&@) {
@@ -1433,7 +1441,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.
@@ -1588,14 +1596,18 @@ Or, simply:
        my $element = $array[ rand @array ];
 
 =head2 How do I permute N elements of a list?
+X<List::Permuter> X<permute> X<Algorithm::Loops> X<Knuth>
+X<The Art of Computer Programming> X<Fischer-Krause>
 
-Use the C<List::Permutor> module on CPAN.  If the list is actually an
+Use the C<List::Permutor> module on CPAN. If the list is actually an
 array, try the C<Algorithm::Permute> module (also on CPAN). It's
-written in XS code and is very efficient.
+written in XS code and is very efficient:
 
        use Algorithm::Permute;
+
        my @array = 'a'..'d';
        my $p_iterator = Algorithm::Permute->new ( \@array );
+
        while (my @perm = $p_iterator->next) {
           print "next permutation: (@perm)\n";
                }
@@ -1603,19 +1615,20 @@ written in XS code and is very efficient.
 For even faster execution, you could do:
 
        use Algorithm::Permute;
+
        my @array = 'a'..'d';
+
        Algorithm::Permute::permute {
                print "next permutation: (@array)\n";
                } @array;
 
-Here's a little program that generates all permutations of
-all the words on each line of input. The algorithm embodied
-in the C<permute()> function is discussed in Volume 4 (still
-unpublished) of Knuth's I<The Art of Computer Programming>
-and will work on any list:
+Here's a little program that generates all permutations of all the
+words on each line of input. The algorithm embodied in the
+C<permute()> function is discussed in Volume 4 (still unpublished) of
+Knuth's I<The Art of Computer Programming> 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;
@@ -1630,7 +1643,22 @@ and will work on any list:
                }
        }
 
-       permute {print"@_\n"} split;
+       permute { print "@_\n" } split;
+
+The C<Algorithm::Loops> module also provides the C<NextPermute> and
+C<NextPermuteNum> functions which efficiently find all unique permutations
+of an array, even if it contains duplicate values, modifying it in-place:
+if its elements are in reverse-sorted order then the array is reversed,
+making it sorted, and it returns false; otherwise the next
+permutation is returned.
+
+C<NextPermute> uses string order and C<NextPermuteNum> numeric order, so
+you can enumerate all the permutations of C<0..9> like this:
+
+       use Algorithm::Loops qw(NextPermuteNum);
+       
+    my @list= 0..9;
+    do { print "@list\n" } while NextPermuteNum @list;
 
 =head2 How do I sort an array by (anything)?
 
@@ -1980,7 +2008,7 @@ And these conditions hold
        $hash{'d'}                       is false
        defined $hash{'d'}               is true
        defined $hash{'a'}               is true
-       exists $hash{'a'}                is true (Perl5 only)
+       exists $hash{'a'}                is true (Perl 5 only)
        grep ($_ eq 'a', keys %hash)     is true
 
 If you now say
@@ -2004,7 +2032,7 @@ and these conditions now hold; changes in caps:
        $hash{'d'}                       is false
        defined $hash{'d'}               is true
        defined $hash{'a'}               is FALSE
-       exists $hash{'a'}                is true (Perl5 only)
+       exists $hash{'a'}                is true (Perl 5 only)
        grep ($_ eq 'a', keys %hash)     is true
 
 Notice the last two: you have an undef value, but a defined key!
@@ -2028,7 +2056,7 @@ and these conditions now hold; changes in caps:
        $hash{'d'}                       is false
        defined $hash{'d'}               is true
        defined $hash{'a'}               is false
-       exists $hash{'a'}                is FALSE (Perl5 only)
+       exists $hash{'a'}                is FALSE (Perl 5 only)
        grep ($_ eq 'a', keys %hash)     is FALSE
 
 See, the whole entry is gone!
@@ -2043,10 +2071,16 @@ end up doing is not what they do with ordinary hashes.
 
 =head2 How do I reset an each() operation part-way through?
 
-Using C<keys %hash> in scalar context returns the number of keys in
-the hash I<and> resets the iterator associated with the hash.  You may
-need to do this if you use C<last> to exit a loop early so that when
-you re-enter it, the hash iterator has been reset.
+(contributed by brian d foy)
+
+You can use the C<keys> or C<values> functions to reset C<each>. To
+simply reset the iterator used by C<each> without doing anything else,
+use one of them in void context:
+
+       keys %hash; # resets iterator, nothing else.
+       values %hash; # resets iterator, nothing else.
+
+See the documentation for C<each> in L<perlfunc>.
 
 =head2 How can I get the unique keys from two hashes?
 
@@ -2260,9 +2294,9 @@ the C<PDL> module from CPAN instead--it makes number-crunching easy.
 
 =head1 REVISION
 
-Revision: $Revision: 8539 $
+Revision: $Revision: 10394 $
 
-Date: $Date: 2007-01-11 00:07:14 +0100 (jeu, 11 jan 2007) $
+Date: $Date: 2007-12-09 18:47:15 +0100 (Sun, 09 Dec 2007) $
 
 See L<perlfaq> for source control details and availability.