X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlfaq4.pod;h=18d709169b3fdfe90ca9271405df93d609f798b5;hb=14aaa8fc27b8350048cdee657c0128eb979d0b2a;hp=bedc668c19cc1d023103346cf6e65b23808e21b6;hpb=f05bbc4047b4e519eb0edbaf2fce2004f4838d1a;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlfaq4.pod b/pod/perlfaq4.pod index bedc668..18d7091 100644 --- a/pod/perlfaq4.pod +++ b/pod/perlfaq4.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq4 - Data Manipulation ($Revision: 1.20 $, $Date: 2002/04/07 18:46:13 $) +perlfaq4 - Data Manipulation ($Revision: 1.25 $, $Date: 2002/05/30 07:04:25 $) =head1 DESCRIPTION @@ -135,7 +135,9 @@ functions is that it works with numbers of ANY size, that it is optimized for speed on some operations, and for at least some programmers the notation might be familiar. -=item B +=over 4 + +=item How do I convert hexadecimal into decimal Using perl's built in conversion of 0x notation: @@ -158,7 +160,7 @@ Using the CPAN module Bit::Vector: $vec = Bit::Vector->new_Hex(32, "DEADBEEF"); $dec = $vec->to_Dec(); -=item B +=item How do I convert from decimal to hexadecimal Using sprint: @@ -181,7 +183,7 @@ And Bit::Vector supports odd bit counts: $vec->Resize(32); # suppress leading 0 if unwanted $hex = $vec->to_Hex(); -=item B +=item How do I convert from octal to decimal Using Perl's built in conversion of numbers with leading zeros: @@ -200,7 +202,7 @@ Using Bit::Vector: $vec->Chunk_List_Store(3, split(//, reverse "33653337357")); $dec = $vec->to_Dec(); -=item B +=item How do I convert from decimal to octal Using sprintf: @@ -212,7 +214,12 @@ Using Bit::Vector $vec = Bit::Vector->new_Dec(32, -559038737); $oct = reverse join('', $vec->Chunk_List_Read(3)); -=item B +=item How do I convert from binary to decimal + +Perl 5.6 lets you write binary numbers directly with +the 0b notation: + + $number = 0b10110110; Using pack and ord @@ -231,7 +238,7 @@ Using Bit::Vector: $vec = Bit::Vector->new_Bin(32, "11011110101011011011111011101111"); $dec = $vec->to_Dec(); -=item B +=item How do I convert from decimal to binary Using unpack; @@ -246,6 +253,7 @@ Using Bit::Vector: The remaining transformations (e.g. hex -> oct, bin -> hex, etc.) are left as an exercise to the inclined reader. +=back =head2 Why doesn't & work the way I want it to? @@ -1391,13 +1399,20 @@ Here's another; let's compute spherical volumes: $_ *= (4/3) * 3.14159; # this will be constant folded } -If you want to do the same thing to modify the values of the hash, -you may not use the C function, oddly enough. You need a slice: +If you want to do the same thing to modify the values of the +hash, you can use the C function. As of Perl 5.6 +the values are not copied, so if you modify $orbit (in this +case), you modify the value. - for $orbit ( @orbits{keys %orbits} ) { + for $orbit ( values %orbits ) { ($orbit **= 3) *= (4/3) * 3.14159; } +Prior to perl 5.6 C returned copies of the values, +so older perl code often contains constructions such as +C<@orbits{keys %orbits}> instead of C where +the hash is to be modified. + =head2 How do I select a random element from an array? Use the rand() function (see L): @@ -1535,6 +1550,13 @@ get those bits into your @ints array: This method gets faster the more sparse the bit vector is. (Courtesy of Tim Bunce and Winfried Koenig.) +You can make the while loop a lot shorter with this suggestion +from Benjamin Goldberg: + + while($vec =~ /[^\0]+/g ) { + push @ints, grep vec($vec, $_, 1), $-[0] * 8 .. $+[0] * 8; + } + Or use the CPAN module Bit::Vector: $vector = Bit::Vector->new($num_of_bits); @@ -1688,15 +1710,17 @@ The Tie::IxHash module from CPAN might also be instructive. =head2 What's the difference between "delete" and "undef" with hashes? -Hashes are pairs of scalars: the first is the key, the second is the -value. The key will be coerced to a string, although the value can be -any kind of scalar: string, number, or reference. If a key C<$key> is -present in the array, C will return true. The value for -a given key can be C, in which case C<$array{$key}> will be -C while C<$exists{$key}> will return true. This corresponds to -(C<$key>, C) being in the hash. +Hashes contain pairs of scalars: the first is the key, the +second is the value. The key will be coerced to a string, +although the value can be any kind of scalar: string, +number, or reference. If a key $key is present in +%hash, C will return true. The value +for a given key can be C, in which case +C<$hash{$key}> will be C while C +will return true. This corresponds to (C<$key>, C) +being in the hash. -Pictures help... here's the C<%ary> table: +Pictures help... here's the %hash table: keys values +------+------+ @@ -1708,16 +1732,16 @@ Pictures help... here's the C<%ary> table: And these conditions hold - $ary{'a'} is true - $ary{'d'} is false - defined $ary{'d'} is true - defined $ary{'a'} is true - exists $ary{'a'} is true (Perl5 only) - grep ($_ eq 'a', keys %ary) is true + $hash{'a'} is true + $hash{'d'} is false + defined $hash{'d'} is true + defined $hash{'a'} is true + exists $hash{'a'} is true (Perl5 only) + grep ($_ eq 'a', keys %hash) is true If you now say - undef $ary{'a'} + undef $hash{'a'} your table now reads: @@ -1732,18 +1756,18 @@ your table now reads: and these conditions now hold; changes in caps: - $ary{'a'} is FALSE - $ary{'d'} is false - defined $ary{'d'} is true - defined $ary{'a'} is FALSE - exists $ary{'a'} is true (Perl5 only) - grep ($_ eq 'a', keys %ary) is true + $hash{'a'} is FALSE + $hash{'d'} is false + defined $hash{'d'} is true + defined $hash{'a'} is FALSE + exists $hash{'a'} is true (Perl5 only) + grep ($_ eq 'a', keys %hash) is true Notice the last two: you have an undef value, but a defined key! Now, consider this: - delete $ary{'a'} + delete $hash{'a'} your table now reads: @@ -1756,23 +1780,22 @@ your table now reads: and these conditions now hold; changes in caps: - $ary{'a'} is false - $ary{'d'} is false - defined $ary{'d'} is true - defined $ary{'a'} is false - exists $ary{'a'} is FALSE (Perl5 only) - grep ($_ eq 'a', keys %ary) is FALSE + $hash{'a'} is false + $hash{'d'} is false + defined $hash{'d'} is true + defined $hash{'a'} is false + exists $hash{'a'} is FALSE (Perl5 only) + grep ($_ eq 'a', keys %hash) is FALSE See, the whole entry is gone! =head2 Why don't my tied hashes make the defined/exists distinction? -They may or may not implement the EXISTS() and DEFINED() methods -differently. For example, there isn't the concept of undef with hashes -that are tied to DBM* files. This means the true/false tables above -will give different results when used on such a hash. It also means -that exists and defined do the same thing with a DBM* file, and what -they end up doing is not what they do with ordinary hashes. +This depends on the tied hash's implementation of EXISTS(). +For example, there isn't the concept of undef with hashes +that are tied to DBM* files. It also means that exists() and +defined() do the same thing with a DBM* file, and what they +end up doing is not what they do with ordinary hashes. =head2 How do I reset an each() operation part-way through? @@ -1901,6 +1924,10 @@ Assuming that you don't care about IEEE notations like "NaN" or if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) { print "a C float\n" } +You can also use the L module on +the CPAN, which exports functions that validate data types +using these and other regular expressions. + If you're on a POSIX system, Perl's supports the C function. Its semantics are somewhat cumbersome, so here's a C wrapper function for more convenient access. This function takes @@ -1924,9 +1951,9 @@ if you just want to say, ``Is this a float?'' sub is_numeric { defined getnum($_[0]) } -Or you could check out the String::Scanf module on CPAN instead. The -POSIX module (part of the standard Perl distribution) provides the -C and C for converting strings to double and longs, +Or you could check out the L module on the CPAN +instead. The POSIX module (part of the standard Perl distribution) provides +the C and C for converting strings to double and longs, respectively. =head2 How do I keep persistent data across program calls?