[Israel.pm] Returning a copy of an object

Shmuel Fomberg semuelf at 012.net.il
Sat Jun 9 14:48:24 PDT 2007


Yossi Itzkovich Said:

>>Other idea: maybe you can implement a copy-on-write scheme?
>>Give your client a reference to a wrapper object, that will pass
trough
>>the reading calls, and will block/alter the writing calls. Or will
copy
>>the relevant data to itself, and perform the call on itself.
>>Of course, that depend on what exactly is going in your system.

>It's a good idea.  Do you know of a module that does it ? I don't want
>to reinvent the wheel (+bugs) .

Haven't heard about a module, and I don't think it's possible to write
generic one. But if your client only calls functions and not accessing
data internally, you can do something like the code below. Be aware that
I haven't tested it. (well, I don't even have Clone installed)

Please note that the client:
1. must not try to access private data: $obj->{secrete}
2. should not try to compare objects. (see the lines marked by Evil)

Shmuel.

### Begin Code ###
package Warpper;
use strict;
use Clone;

sub new {
   my ($class, $orig_ref, $allow_hashref) = @_;
   my $prefix = ref($orig_ref)."::";
   return bless [$prefix, undef, $allow_hashref, $orig_ref], $class;
}

our $AUTOLOAD;

sub AUTOLOAD {
    no strict 'refs';
    my ($self) = @_;
    my $func_name = $AUTOLOAD;
    $func_name =~ s/.*:://;
    if ($self->[1]) {
        $_[0] = $self->[1]; # Evil
        goto &{$self->[0].$func_name};
    }
    if (exists($self->[2]->{$func_name})) {
        shift;
        unshift @_, $self->[3];
        goto &{$self->[0].$func_name};
    }
    $self->[1] = clone($self->[3]);
    $self->[3] = undef;
    $self->[2] = undef;
    $_[0] = $self->[1]; # Evil
    goto &{$self->[0].$func_name};
}

sub DESTROY  {}

1;
### End Code ###






More information about the Perl mailing list