📄 storable.pm
字号:
The C<Storable::last_op_in_netorder()> predicate will tell you whethernetwork order was used in the last store or retrieve operation. If youdon't know how to use this, just forget about it.=item C<Storable::is_storing>Returns true if within a store operation (via STORABLE_freeze hook).=item C<Storable::is_retrieving>Returns true if within a retrieve operation (via STORABLE_thaw hook).=back=head2 RecursionWith hooks comes the ability to recurse back to the Storable engine.Indeed, hooks are regular Perl code, and Storable is convenient whenit comes to serializing and deserializing things, so why not use itto handle the serialization string?There are a few things you need to know, however:=over 4=item *You can create endless loops if the things you serialize via freeze()(for instance) point back to the object we're trying to serialize inthe hook.=item *Shared references among objects will not stay shared: if we're serializingthe list of object [A, C] where both object A and C refer to the SAME objectB, and if there is a serializing hook in A that says freeze(B), then whendeserializing, we'll get [A', C'] where A' refers to B', but C' refers to D,a deep clone of B'. The topology was not preserved.=backThat's why C<STORABLE_freeze> lets you provide a list of referencesto serialize. The engine guarantees that those will be serialized in thesame context as the other objects, and therefore that shared objects willstay shared.In the above [A, C] example, the C<STORABLE_freeze> hook could return: ("something", $self->{B})and the B part would be serialized by the engine. In C<STORABLE_thaw>, youwould get back the reference to the B' object, deserialized for you.Therefore, recursion should normally be avoided, but is nonetheless supported.=head2 Deep CloningThere is a Clone module available on CPAN which implements deep cloningnatively, i.e. without freezing to memory and thawing the result. It isaimed to replace Storable's dclone() some day. However, it does not currentlysupport Storable hooks to redefine the way deep cloning is performed.=head1 Storable magicYes, there's a lot of that :-) But more precisely, in UNIX systemsthere's a utility called C<file>, which recognizes data files based ontheir contents (usually their first few bytes). For this to work,a certain file called F<magic> needs to taught about the I<signature>of the data. Where that configuration file lives depends on the UNIXflavour; often it's something like F</usr/share/misc/magic> orF</etc/magic>. Your system administrator needs to do the updating ofthe F<magic> file. The necessary signature information is output toSTDOUT by invoking Storable::show_file_magic(). Note that the GNUimplementation of the C<file> utility, version 3.38 or later,is expected to contain support for recognising Storable filesout-of-the-box, in addition to other kinds of Perl files.You can also use the following functions to extract the file headerinformation from Storable images:=over=item $info = Storable::file_magic( $filename )If the given file is a Storable image return a hash describing it. Ifthe file is readable, but not a Storable image return C<undef>. Ifthe file does not exist or is unreadable then croak.The hash returned has the following elements:=over=item C<version>This returns the file format version. It is a string like "2.7".Note that this version number is not the same as the version number ofthe Storable module itself. For instance Storable v0.7 create filesin format v2.0 and Storable v2.15 create files in format v2.7. Thefile format version number only increment when additional featuresthat would confuse older versions of the module are added.Files older than v2.0 will have the one of the version numbers "-1","0" or "1". No minor number was used at that time.=item C<version_nv>This returns the file format version as number. It is a string like"2.007". This value is suitable for numeric comparisons.The constant function C<Storable::BIN_VERSION_NV> returns a comparablenumber that represent the highest file version number that thisversion of Storable fully support (but see discussion ofC<$Storable::accept_future_minor> above). The constantC<Storable::BIN_WRITE_VERSION_NV> function returns what file versionis written and might be less than C<Storable::BIN_VERSION_NV> in someconfiguations.=item C<major>, C<minor>This also returns the file format version. If the version is "2.7"then major would be 2 and minor would be 7. The minor element ismissing for when major is less than 2.=item C<hdrsize>The is the number of bytes that the Storable header occupies.=item C<netorder>This is TRUE if the image store data in network order. This meansthat it was created with nstore() or similar.=item C<byteorder>This is only present when C<netorder> is FALSE. It is the$Config{byteorder} string of the perl that created this image. It isa string like "1234" (32 bit little endian) or "87654321" (64 bit bigendian). This must match the current perl for the image to bereadable by Storable.=item C<intsize>, C<longsize>, C<ptrsize>, C<nvsize>These are only present when C<netorder> is FALSE. These are the sizes ofvarious C datatypes of the perl that created this image. These mustmatch the current perl for the image to be readable by Storable.The C<nvsize> element is only present for file format v2.2 andhigher.=item C<file>The name of the file.=back=item $info = Storable::read_magic( $buffer )=item $info = Storable::read_magic( $buffer, $must_be_file )The $buffer should be a Storable image or the first few bytes of it.If $buffer starts with a Storable header, then a hash describing theimage is returned, otherwise C<undef> is returned.The hash has the same structure as the one returned byStorable::file_magic(). The C<file> element is true if the image is afile image.If the $must_be_file argument is provided and is TRUE, then returnC<undef> unless the image looks like it belongs to a file dump.The maximum size of a Storable header is currently 21 bytes. If theprovided $buffer is only the first part of a Storable image it shouldat least be this long to ensure that read_magic() will recognize it assuch.=back=head1 EXAMPLESHere are some code samples showing a possible usage of Storable: use Storable qw(store retrieve freeze thaw dclone); %color = ('Blue' => 0.1, 'Red' => 0.8, 'Black' => 0, 'White' => 1); store(\%color, 'mycolors') or die "Can't store %a in mycolors!\n"; $colref = retrieve('mycolors'); die "Unable to retrieve from mycolors!\n" unless defined $colref; printf "Blue is still %lf\n", $colref->{'Blue'}; $colref2 = dclone(\%color); $str = freeze(\%color); printf "Serialization of %%color is %d bytes long.\n", length($str); $colref3 = thaw($str);which prints (on my machine): Blue is still 0.100000 Serialization of %color is 102 bytes long.Serialization of CODE references and deserialization in a safecompartment:=for example begin use Storable qw(freeze thaw); use Safe; use strict; my $safe = new Safe; # because of opcodes used in "use strict": $safe->permit(qw(:default require)); local $Storable::Deparse = 1; local $Storable::Eval = sub { $safe->reval($_[0]) }; my $serialized = freeze(sub { 42 }); my $code = thaw($serialized); $code->() == 42;=for example end=for example_testing is( $code->(), 42 );=head1 WARNINGIf you're using references as keys within your hash tables, you're boundto be disappointed when retrieving your data. Indeed, Perl stringifiesreferences used as hash table keys. If you later wish to access theitems via another reference stringification (i.e. using the samereference that was used for the key originally to record the value intothe hash table), it will work because both references stringify to thesame string.It won't work across a sequence of C<store> and C<retrieve> operations,however, because the addresses in the retrieved objects, which arepart of the stringified references, will probably differ from theoriginal addresses. The topology of your structure is preserved,but not hidden semantics like those.On platforms where it matters, be sure to call C<binmode()> on thedescriptors that you pass to Storable functions.Storing data canonically that contains large hashes can besignificantly slower than storing the same data normally, astemporary arrays to hold the keys for each hash have to be allocated,populated, sorted and freed. Some tests have shown a halving of thespeed of storing -- the exact penalty will depend on the complexity ofyour data. There is no slowdown on retrieval.=head1 BUGSYou can't store GLOB, FORMLINE, etc.... If you can define semanticsfor those operations, feel free to enhance Storable so that it candeal with them.The store functions will C<croak> if they run into such referencesunless you set C<$Storable::forgive_me> to some C<TRUE> value. In thatcase, the fatal message is turned in a warning and somemeaningless string is stored instead.Setting C<$Storable::canonical> may not yield frozen strings thatcompare equal due to possible stringification of numbers. When thestring version of a scalar exists, it is the form stored; therefore,if you happen to use your numbers as strings between two freezingoperations on the same data structures, you will get differentresults.When storing doubles in network order, their value is stored as text.However, you should also not expect non-numeric floating-point valuessuch as infinity and "not a number" to pass successfully through anstore()/retrieve() pair.As Storable neither knows nor cares about character sets (although itdoes know that characters may be more than eight bits wide), any differencein the interpretation of character codes between a host and a targetsystem is your problem. In particular, if host and target use differentcode points to represent the characters used in the text representationof floating-point numbers, you will not be able be able to exchangefloating-point data, even with nstore().C<Storable::drop_utf8> is a blunt tool. There is no facility either toreturn B<all> strings as utf8 sequences, or to attempt to convert utf8data back to 8 bit and C<croak()> if the conversion fails.Prior to Storable 2.01, no distinction was made between signed andunsigned integers on storing. By default Storable prefers to store ascalars string representation (if it has one) so this would only causeproblems when storing large unsigned integers that had never been convertedto string or floating point. In other words values that had been generatedby integer operations such as logic ops and then not used in any string orarithmetic context before storing.=head2 64 bit data in perl 5.6.0 and 5.6.1This section only applies to you if you have existing data written outby Storable 2.02 or earlier on perl 5.6.0 or 5.6.1 on Unix or Linux whichhas been configured with 64 bit integer support (not the default)If you got a precompiled perl, rather than running Configure to buildyour own perl from source, then it almost certainly does not affect you,and you can stop reading now (unless you're curious). If you're using perlon Windows it does not affect you.Storable writes a file header which contains the sizes of various Clanguage types for the C compiler that built Storable (when not writing innetwork order), and will refuse to load files written by a Storable noton the same (or compatible) architecture. This check and a check onmachine byteorder is needed because the size of various fields in the fileare given by the sizes of the C language types, and so files written ondifferent architectures are incompatible. This is done for increased speed.(When writing in network order, all fields are written out as standardlengths, which allows full interworking, but takes longer to read and write)Perl 5.6.x introduced the ability to optional configure the perl interpreterto use C's C<long long> type to allow scalars to store 64 bit integers on 32bit systems. However, due to the way the Perl configuration systemgenerated the C configuration files on non-Windows platforms, and the wayStorable generates its header, nothing in the Storable file header reflectedwhether the perl writing was using 32 or 64 bit integers, despite the factthat Storable was storing some data differently in the file. Hence Storablerunning on perl with 64 bit integers will read the header from a filewritten by a 32 bit perl, not realise that the data is actually in a subtlyincompatible format, and then go horribly wrong (possibly crashing) if itencountered a stored integer. This is a design failure.Storable has now been changed to write out and read in a file header withinformation about the size of integers. It's impossible to detect whetheran old file being read in was written with 32 or 64 bit integers (they havethe same header) so it's impossible to automatically switch to a correctbackwards compatibility mode. Hence this Storable defaults to the new,correct behaviour.What this means is that if you have data written by Storable 1.x runningon perl 5.6.0 or 5.6.1 configured with 64 bit integers on Unix or Linuxthen by default this Storable will refuse to read it, giving the errorI<Byte order is not compatible>. If you have such data then you youshould set C<$Storable::interwork_56_64bit> to a true value to make thisStorable read and write files with the old header. You should alsomigrate your data, or any older perl you are communicating with, to thiscurrent version of Storable.If you don't have data written with specific configuration of perl describedabove, then you do not and should not do anything. Don't set the flag -not only will Storable on an identically configured perl refuse to load them,but Storable a differently configured perl will load them believing themto be correct for it, and then may well fail or crash part way throughreading them.=head1 CREDITSThank you to (in chronological order): Jarkko Hietaniemi <jhi@iki.fi> Ulrich Pfeifer <pfeifer@charly.informatik.uni-dortmund.de> Benjamin A. Holzman <bah@ecnvantage.com> Andrew Ford <A.Ford@ford-mason.co.uk> Gisle Aas <gisle@aas.no> Jeff Gresham <gresham_jeffrey@jpmorgan.com> Murray Nesbitt <murray@activestate.com> Marc Lehmann <pcg@opengroup.org> Justin Banks <justinb@wamnet.com> Jarkko Hietaniemi <jhi@iki.fi> (AGAIN, as perl 5.7.0 Pumpkin!) Salvador Ortiz Garcia <sog@msg.com.mx> Dominic Dunlop <domo@computer.org> Erik Haugan <erik@solbors.no>for their bug reports, suggestions and contributions.Benjamin Holzman contributed the tied variable support, Andrew Fordcontributed the canonical order for hashes, and Gisle Aas fixeda few misunderstandings of mine regarding the perl internals,and optimized the emission of "tags" in the output streams bysimply counting the objects instead of tagging them (leading toa binary incompatibility for the Storable image starting at version0.6--older images are, of course, still properly understood).Murray Nesbitt made Storable thread-safe. Marc Lehmann added overloadingand references to tied items support.=head1 AUTHORStorable was written by Raphael Manfredi F<E<lt>Raphael_Manfredi@pobox.comE<gt>>Maintenance is now done by the perl5-porters F<E<lt>perl5-porters@perl.orgE<gt>>Please e-mail us with problems, bug fixes, comments and complaints,although if you have complements you should send them to Raphael.Please don't e-mail Raphael with problems, as he no longer works onStorable, and your message will be delayed while he forwards it to us.=head1 SEE ALSOL<Clone>.=cut
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -