⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perlfaq4.pod

📁 MSYS在windows下模拟了一个类unix的终端
💻 POD
📖 第 1 页 / 共 5 页
字号:
That's not particularly efficient.  It would be more space-efficientto use:    while (($key, $value) = each %by_key) {	$by_value{$value} = $key;    }If your hash could have repeated values, the methods above will only findone of the associated keys.   This may or may not worry you.  If it doesworry you, you can always reverse the hash into a hash of arrays instead:     while (($key, $value) = each %by_key) {	 push @{$key_list_by_value{$value}}, $key;     }=head2 How can I know how many entries are in a hash?If you mean how many keys, then all you have to do istake the scalar sense of the keys() function:    $num_keys = scalar keys %hash;The keys() function also resets the iterator, which in void context isfaster for tied hashes than would be iterating through the whole hash, one key-value pair at a time.=head2 How do I sort a hash (optionally by value instead of key)?Internally, hashes are stored in a way that prevents you from imposingan order on key-value pairs.  Instead, you have to sort a list of thekeys or values:    @keys = sort keys %hash;	# sorted by key    @keys = sort {		    $hash{$a} cmp $hash{$b}	    } keys %hash; 	# and by valueHere we'll do a reverse numeric sort by value, and if two keys areidentical, sort by length of key, or if that fails, by straight ASCIIcomparison of the keys (well, possibly modified by your locale--seeL<perllocale>).    @keys = sort {		$hash{$b} <=> $hash{$a}			  ||		length($b) <=> length($a)			  ||		      $a cmp $b    } keys %hash;=head2 How can I always keep my hash sorted?You can look into using the DB_File module and tie() using the$DB_BTREE hash bindings as documented in L<DB_File/"In Memory Databases">.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 thevalue.  The key will be coerced to a string, although the value can beany kind of scalar: string, number, or reference.  If a key C<$key> ispresent in the array, C<exists($key)> will return true.  The value fora given key can be C<undef>, in which case C<$array{$key}> will beC<undef> while C<$exists{$key}> will return true.  This corresponds to(C<$key>, C<undef>) being in the hash.Pictures help...  here's the C<%ary> table:	  keys  values	+------+------+	|  a   |  3   |	|  x   |  7   |	|  d   |  0   |	|  e   |  2   |	+------+------+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 trueIf you now say	undef $ary{'a'}your table now reads:	  keys  values	+------+------+	|  a   | undef|	|  x   |  7   |	|  d   |  0   |	|  e   |  2   |	+------+------+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 trueNotice the last two: you have an undef value, but a defined key!Now, consider this:	delete $ary{'a'}your table now reads:	  keys  values	+------+------+	|  x   |  7   |	|  d   |  0   |	|  e   |  2   |	+------+------+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 FALSESee, 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() methodsdifferently.  For example, there isn't the concept of undef with hashesthat are tied to DBM* files. This means the true/false tables abovewill give different results when used on such a hash.  It also meansthat exists and defined do the same thing with a DBM* file, and whatthey 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 inthe hash I<and> resets the iterator associated with the hash.  You mayneed to do this if you use C<last> to exit a loop early so that when youre-enter it, the hash iterator has been reset.=head2 How can I get the unique keys from two hashes?First you extract the keys from the hashes into lists, then solvethe "removing duplicates" problem described above.  For example:    %seen = ();    for $element (keys(%foo), keys(%bar)) {	$seen{$element}++;    }    @uniq = keys %seen;Or more succinctly:    @uniq = keys %{{%foo,%bar}};Or if you really want to save space:    %seen = ();    while (defined ($key = each %foo)) {        $seen{$key}++;    }    while (defined ($key = each %bar)) {        $seen{$key}++;    }    @uniq = keys %seen;=head2 How can I store a multidimensional array in a DBM file?Either stringify the structure yourself (no fun), or elseget the MLDBM (which uses Data::Dumper) module from CPAN and layerit on top of either DB_File or GDBM_File.=head2 How can I make my hash remember the order I put elements into it?Use the Tie::IxHash from CPAN.    use Tie::IxHash;    tie(%myhash, Tie::IxHash);    for ($i=0; $i<20; $i++) {        $myhash{$i} = 2*$i;    }    @keys = keys %myhash;    # @keys = (0,1,2,3,...)=head2 Why does passing a subroutine an undefined element in a hash create it?If you say something like:    somefunc($hash{"nonesuch key here"});Then that element "autovivifies"; that is, it springs into existencewhether you store something there or not.  That's because functionsget scalars passed in by reference.  If somefunc() modifies C<$_[0]>,it has to be ready to write it back into the caller's version.This has been fixed as of Perl5.004.Normally, merely accessing a key's value for a nonexistent key doesI<not> cause that key to be forever there.  This is different thanawk's behavior.=head2 How can I make the Perl equivalent of a C structure/C++ class/hash or array of hashes or arrays?Usually a hash ref, perhaps like this:    $record = {        NAME   => "Jason",        EMPNO  => 132,        TITLE  => "deputy peon",        AGE    => 23,        SALARY => 37_000,        PALS   => [ "Norbert", "Rhys", "Phineas"],    };References are documented in L<perlref> and the upcoming L<perlreftut>.Examples of complex data structures are given in L<perldsc> andL<perllol>.  Examples of structures and object-oriented classes arein L<perltoot>.=head2 How can I use a reference as a hash key?You can't do this directly, but you could use the standard Tie::Refhashmodule distributed with Perl.=head1 Data: Misc=head2 How do I handle binary data correctly?Perl is binary clean, so this shouldn't be a problem.  For example,this works fine (assuming the files are found):    if (`cat /vmunix` =~ /gzip/) {	print "Your kernel is GNU-zip enabled!\n";    }On less elegant (read: Byzantine) systems, however, you haveto play tedious games with "text" versus "binary" files.  SeeL<perlfunc/"binmode"> or L<perlopentut>.  Most of these ancient-thinkingsystems are curses out of Microsoft, who seem to be committed to puttingthe backward into backward compatibility.If you're concerned about 8-bit ASCII data, then see L<perllocale>.If you want to deal with multibyte characters, however, there aresome gotchas.  See the section on Regular Expressions.=head2 How do I determine whether a scalar is a number/whole/integer/float?Assuming that you don't care about IEEE notations like "NaN" or"Infinity", you probably just want to use a regular expression.   if (/\D/)            { print "has nondigits\n" }   if (/^\d+$/)         { print "is a whole number\n" }   if (/^-?\d+$/)       { print "is an integer\n" }   if (/^[+-]?\d+$/)    { print "is a +/- integer\n" }   if (/^-?\d+\.?\d*$/) { print "is a real number\n" }   if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "is a decimal number" }   if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)			{ print "a C float" }If you're on a POSIX system, Perl's supports the C<POSIX::strtod>function.  Its semantics are somewhat cumbersome, so here's a C<getnum>wrapper function for more convenient access.  This function takesa string and returns the number it found, or C<undef> for input thatisn't a C float.  The C<is_numeric> function is a front end to C<getnum>if you just want to say, ``Is this a float?''    sub getnum {        use POSIX qw(strtod);        my $str = shift;        $str =~ s/^\s+//;        $str =~ s/\s+$//;        $! = 0;        my($num, $unparsed) = strtod($str);        if (($str eq '') || ($unparsed != 0) || $!) {            return undef;        } else {            return $num;        }     }     sub is_numeric { defined getnum($_[0]) } Or you could check out the String::Scanf module on CPAN instead.  ThePOSIX module (part of the standard Perl distribution) provides theC<strtod> and C<strtol> for converting strings to double and longs,respectively.=head2 How do I keep persistent data across program calls?For some specific applications, you can use one of the DBM modules.See L<AnyDBM_File>.  More generically, you should consult the FreezeThaw,Storable, or Class::Eroot modules from CPAN.  Here's one example usingStorable's C<store> and C<retrieve> functions:    use Storable;     store(\%hash, "filename");    # later on...      $href = retrieve("filename");        # by ref    %hash = %{ retrieve("filename") };   # direct to hash=head2 How do I print out or copy a recursive data structure?The Data::Dumper module on CPAN (or the 5.005 release of Perl) is greatfor printing out data structures.  The Storable module, found on CPAN,provides a function called C<dclone> that recursively copies its argument.    use Storable qw(dclone);     $r2 = dclone($r1);Where $r1 can be a reference to any kind of data structure you'd like.It will be deeply copied.  Because C<dclone> takes and returns references,you'd have to add extra punctuation if you had a hash of arrays thatyou wanted to copy.    %newhash = %{ dclone(\%oldhash) };=head2 How do I define methods for every class/object?Use the UNIVERSAL class (see L<UNIVERSAL>).=head2 How do I verify a credit card checksum?Get the Business::CreditCard module from CPAN.=head2 How do I pack arrays of doubles or floats for XS code?The kgbpack.c code in the PGPLOT module on CPAN does just this.If you're doing a lot of float or double processing, consider usingthe PDL module from CPAN instead--it makes number-crunching easy.=head1 AUTHOR AND COPYRIGHTCopyright (c) 1997-1999 Tom Christiansen and Nathan Torkington.All rights reserved.When included as part of the Standard Version of Perl, or as part ofits complete documentation whether printed or otherwise, this workmay be distributed only under the terms of Perl's Artistic License.Any distribution of this file or derivatives thereof I<outside>of that package require that special arrangements be made withcopyright holder.Irrespective of its distribution, all code examples in this fileare hereby placed into the public domain.  You are permitted andencouraged to use this code in your own programs for funor for profit as you see fit.  A simple comment in the code givingcredit would be courteous but is not required.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -