|
NAMEClone::Fast - Natively copying Perl data structuresSYNOPSISuse strict; use warnings; use Clone::Fast qw( clone ); use Data::Dumper; # Though that may be the easiest thing to do, there # are also other options: # # use Clone::Fast; # While using Clone::Fast::clone # { # no strict 'refs'; # *clone = \&Clone::Fast::clone; # } # # eval( "sub clone { Clone::Fast::clone }" ); my $original = bless( { 'a' => [ qw( a b c d ) ] }, 'main' ); my $copy = clone( $original ); # Notice the original and copy are no longer the same, # although they look exactly the same print "Different memory segments\n" if ( $original ne $copy ); print "Same structure\n" if ( Dumper( $original ) eq Dumper( $copy ) ); DESCRIPTIONEssentially, this module is a very optimized version of Clone::More. By taking advantage of one of Clone::More's 'OPTIMIZATION_HACKS' as well as removing all the Pure Perl from the "More.pm", I was able to gain a lot of speed out of the module. Essentially, though, the core of the module is exactly as that of Clone::More.You will see that by useing Benchmark::cmpthese, I ran a simple comparison between Storable::dclone, Clone::More::clone, and Clone::Fast::clone. You will (should) begin to see the reason why I loaded this module along side of Clone::More. Rate Storable Clone::More Clone::Fast Storable 7552/s -- -39% -59% Clone::More 12400/s 64% -- -33% Clone::Fast 18442/s 144% 49% -- For more information relative to the DESCRIPTION of this module, I recommend peeking into the POD written for Clone::More (I took more time with it ;) ) EXPORTcloneClone is the primary function from within the provided module. By passing a scalar reference to this routine, you will expect to get a returned scalar reference that will no longer have any reference to the originating reference. However, references deeper into the structure will still uphold the references within the structure. Example being: use Clone::Fast qw( clone ); my $foo = { 'a' => 'b' }; my $bar = { 'a' => $foo, 'b' => $foo }; my $baz = clone( $bar ); print "\$foo and \$bar are different references\n" if ( $foo ne $bar ); print "\$foo->{'a'} and \$bar->{'a'} are different references\n" if ( $foo->{'a'} ne $bar->{'a'} ); print "\$foo->{'a'} and \$foo->{'b'} are the same, however\n" if ( $foo->{'a'} eq $bar->{'b'} ); This makes sense, although this can be modified as well. By using the internal variable, BREAK_REFS, you are also allowed to break internal references (may break up circular references, although won't fix the circular reference in the originating reference). PROGRAMATIC HOOKSMuch like the Perl Storable module (available in all current Perl distributions), "Clone::Fast" allows for hooks that will be accessed when cloning any object that has a hook defined. This can be very handy where Inside Out objects would not normally be cloned. WHHAAATT???? What I mean is, only the reference of an object will be cloned, not the internal stash of the object. Therefore, accessors that are defined within an inside out object will not be cloned. There is no real safe way to do this, with the exception of cloning the entire class stash, breaking more things than it will fix. Again, the reference of the object will be fully cloned, and the object it's self will be a new reference, although it will be an empty object. Subsiquently, such as most inside out objects, the blessed reference is of a scalar type; an integer indicating the object id. When cloning this, you would end up with two objects of the same type with the same object id. The hooks have been added in an attempt to prevent this from happening.CLONEFAST_cloneAgain, much like Storable (though a little better, I hope), the function will be called *AFTER* the clone operation has completed on the object being cloned. The routine will have two scalar references passed via the stack, representing both the cloned object as well as the source of the clone. This *should* allow for the programatic manipulation of the object before it gets returned to the caller, or placed into the refering structure.As an example, I will use the following object to define a 'hooked' object: package Hookable; use strict; use warnings; use Clone::Fast qw( clone ); sub new { bless {}, shift } sub CLONEFAST_clone { # Where clone is the cloned object from the source, where source # was the originating reference my ( $clone, $source ) = @_; # I am going to pretend the source has a list of defined methods, # of which I want to clone and transfer to the clone; outside # of the blessed hash-refrence that is the source of the object $clone->$_( clone( $source->$_() ) ) for ( qw( get_method_1 get_method_2 get_method_3 ) ); # At this point, the cloned object will also have a set of cloned # fields from the source. If, by chance, any of the values of the # defined attribtes are other 'Hookable' objects, the same routine # will be called on that object as well. # The API requires me to return the new $clone, this will be returned to # the caller return $clone; } Using the package from above, I will now use an example of a script where I will demonstrate how the whole thing comes together: #!/usr/bin/perl -w use strict; use Clone::Fast qw( clone ); my $hookable = Hookable->new(); $hookable->{'hash_stuff'} = 'some value'; my $structure = { 'hookable' => $hookable, 'new' => Hookable->new(), 'deeply' => { 'hookable' => $hookable, 'new' => Hookable->new(); }, }; my $cloned = clone( $sturcture ); This script will demonstrate a number of things. 1.) "Clone::Fast::clone" will, automagically call the hook on all instances of the Hookable. Though the hash_stuff key will automatically be cloned before the hook is ever called. Subsiquently, the hashes in both values of hookable in the hash will be references of one another, though not references to the originating object. The Hookable->new() object, on the other hand, will not be referenced to anything of the similar like. As a secondary note, it was originally thought to allow for hooks to show up before and after the cloning of the object. Though, that would allow for the full change of the cloning type; this would be very bad. Also, given that it is somewhat reasonable to believe hooks will only be used with inside out objects, we can also assume the cloning of a simple referent will be so lightweight that there will still be the benifit of having clone hook into the object. If anyone has beef with this paradigm, let me know and I'll change it. CONFIGURATION VARIABLES
EXAMPLES
GOTCHAS/WARNINGS
SEE ALSO
AUTHORTrevor Hall, <wazzuteke@cpan.org>COPYRIGHT AND LICENSECopyright (C) 2006-2012 by Trevor HallThis is free software, licensed under: The Artistic License 2.0 (GPL Compatible)
Visit the GSP FreeBSD Man Page Interface. |