1: package Object::Clone;
   3: use strict;
   4: use vars qw($VERSION);
   5: use Data::Dumper;
   7: $VERSION = '0.02';
   9: sub clone {
  10:         my $self = shift;
  12:         my $VAR1;
  13:         my $copy_dump = Dumper $self;
  15:         eval $copy_dump; warn $@ if $@;
  17:         return $VAR1; 
  18: }
  20: =pod
  22: =head1 NAME
  24: Object::Clone
  26: =head1 SYNOPSIS
  28: package Myclass;
  30: @ISA = qw(Object::Clone);
  32: my object1 = Myclass->new(attribute => 'argle');
  33: my object2 = object1->clone;
  35: =head1 DESCRIPTION
  37: This class offers a simple cloning method. So you can make copies of your object
  38: s fast.
  40: =over
  42: =item clone
  44: The method use to clone objects. Takes no arguments, just has to be called as a 
  45: regular method (cause it is) and returns a new object.
  47: =back
  49: =head1 AUTHOR
  52: jonasbn <>
  54: =head1 BUGS
  56: No known bugs. 
  58: =head1 SEE ALSO
  60: L<Data::Dumper>
  62: =head1 COPYRIGHT
  64: Copyright (c) 2001 Jonas B. Nielsen. All rights
  65: reserved.  This program is free software; you can
  66: redistribute it and/or modify it under the same 
  67: terms as Perl itself.
  69: Drop me a mail - it will be appreciated.
  71: Home of this code is
  73: =cut
  75: 1;

Replies are listed 'Best First'.
Re: Object::Clone a simple class providing a cloning method
by dws (Chancellor) on Nov 19, 2001 at 02:43 UTC
    How to correctly clone an object is a problem that people run into again and again and again, and the answer each time is that no general solution is possible.

    Without semantic knowledge, it is not always possible to know in advance whether a shallow copy of the object is sufficient, whether a deep copy is required, or whether a correct copy requires something in between the two.

    A shallow copy of an object treats instance data as static data that can be simply copied into a new instance. For some objects, including those based on arrays or hashes where all values are simple scalars, this works. But as soon as a value is a reference to another object, you have to make a choice between simply copying the reference (i.e., making a shallow copy), or recursively cloning the referred-to object (i.e., making a deep copy). In a moderately sophisticated system, you're liable to run into objects that require some combination of shallow and deep copying in order to be successfully cloned.

Re: Object::Clone a simple class providing a cloning method
by premchai21 (Curate) on Nov 18, 2001 at 23:54 UTC
    The problem here is that if your object contains references to other objects, the other objects get cloned too; if that is what you want, then Storable already provides dclone. You could copy only unblessed references by doing something like this:
    sub sclone { while (defined(my $what = shift)) { for my $r (ref $what) { ($r eq 'ARRAY') && return [map { sclone $_ } @$r]; ($r eq 'HASH') && return do { my %s = map { $_ => sclone ($$r{$_}) } keys %$r}; \%s; }; ($r eq 'SCALAR') && return do { my $s = $$r; \$s; }; return $r; } } }
    This can still cause problems, though... suppose you have a reference to a class variable? Now it points to an anonymous scalar, which isn't what you want. But suppose you have a reference to an anonymous scalar, and you just copy the reference directly? Now you have a pointer to the same anonymous scalar, which isn't what you want. There's no real way programatically to tell the difference, unless it's specified in the class somewhere... and if it is, then IMHO the class might as well have its own clone routine.
Re: Object::Clone a simple class providing a cloning method
by belg4mit (Prior) on Nov 18, 2001 at 23:05 UTC
    -13: my $copy_dump = Dumper $self; -14: -15: eval $copy_dump; warn $@ if $@; +13: eval Dumper($self); warn $@ if $@;
    Untested but that ought to work.

    perl -p -e "s/(?:\w);([st])/'\$1/mg"

Re: Object::Clone a simple class providing a cloning method
by IlyaM (Parson) on Nov 26, 2001 at 05:36 UTC
    You can clone objects with CPAN module Storable.

    use Storable (dclone); ... my $obj2 = dclone($obj1);

    It should be faster since Storable is XS (though I haven't done any benchmarks so I can be wrong).

    Another option is CPAN module Clone. I've never tried it myself so I can't say anything about it.