RE: RFC 67 (v1) Deep Copying, aka, cloning around.

2000-08-09 Thread Garrett Goebel

From: Peter Scott [mailto:[EMAIL PROTECTED]]

 I would like deep copying to include copying CODE. It would 
 be useful for implementing object methods...
 
 Why would it be necessary to deep copy a CODE reference?

It might not be necessary. I'm still learning how to write kosher Perl...
elegance is a long way off for me.  

It'd be nice to for a class to be able to initialize a new object containing
a copy of an anonymous subroutine instead of a reference to a common one.
There might be some real justification when used with closures. Then class
methods could pass through to object methods that could be switched at
runtime.

Besides, it wouldn't be deep copying if it shallow copied the subroutines ;)

If deep copying and cloning are though of in terms of persistent objects...
aka Data::Dumper and Storable, then deparsing subroutines into something
that can be stored becomes more important too.  Class::Tom does this pretty
well.

Garrett



RE: RFC 67 (v1) Deep Copying, aka, cloning around.

2000-08-08 Thread Garrett Goebel

Here's a version of my own kludgey deep copy. -Updated to use our mythical
-CLONE method, and watch for circular references...

our %SEEN = ();
our $DEPTH = 0;

%a = (a = 1, b = 2, c = [{a = 1, b = [1,2,3]}, 1, 2, 3]);
*b = dcopy(\%a);

sub dcopy { # Dereference and return a deep copy of whatever's passed
our %SEEN;
local $_ = ref($_[0]) or return $_[0];
exists $SEEN{$_} and return $SEEN{$_};
$DEPTH++;

my $rval =  
  /^HASH$/   ? {map {dcopy($_)} (%{$_[0]})}
: /^ARRAY$/  ? [map {dcopy($_)} @{$_[0]} ]
: /^SCALAR$/ ? \${$_[0]}
: /^FORMAT$/ ? $_[0]# Shallow copy until we figure out
: /^Regexp$/ ? $_[0]# B.pm and Class::Tom show the way
: /^REF$/? $_[0]# how to deep copy these. Note:
: /^IO$/ ? $_[0]# "
: /^GLOB$/   ? $_[0]# "
: /^CODE$/   ? $_[0]# " (B::Deparse)
: $_[0]-CLONE;

--$DEPTH 
and $SEEN{$_} = ref($rval)
or  $SEEN = (); 
$rval;
}

   (/^$/ || /^CODE$/)  return $obj;
/^SCALAR|REF$/ return \clone $$obj;
/^ARRAY$/  return [ map clone($_), @$obj ];
/^HASH$/   return { map {$_, clone $obj-{$_}} 
 keys %$obj };
 
 TODO: behavior for CGLOB, CREGEX, and CLVALUE.

I would like deep copying to include copying CODE. It would be useful for
implementing object methods...

 =head2 Filehandles
 
 If Cclone encounters an CIO::Handle, its default behavior 
 will be to  make a copy of the filehandle (debatable: perhaps
 the default should be to throw an exception) unless a CCALLBACK
 function was specified

Doesn't this fall under $obj-CLONE?

Speaking of UNIVERSAL::CLONE is it really more complicated than a special
case of the above dcopy subroutine? Hmm... I guess I'm not covering tied
variables...

our %SEEN = ();
our $DEPTH = 0;

sub CLONE { # Dereference and return a deep copy of whatever's passed
our %SEEN;
my $ref = ref($_[0]) or return $_[0];
exists $SEEN{$_} and return $SEEN{$_};
$DEPTH++;

my ($a,$z) = (qr/(^|^.*?=)/, qr/\(.*?\)$/);
my $r =
  ($_[0] =~ /${a}HASH$z/)   ? {map {dcopy($_)} (%{$_[1]})}
: ($_[0] =~ /${a}ARRAY$z/)  ? [map {dcopy($_)} @{$_[1]} ]
: ($_[0] =~ /${a}SCALAR$z/) ? \${$_[1]}
: ($_[0] =~ /${a}FORMAT$z/) ? $_[0]
: ($_[0] =~ /${a}CODE$z/)   ? $_[0]
: ($_[0] =~ /${a}Regexp$z/) ? $_[0]
: ($_[0] =~ /${a}REF$z/)? $_[0]
: ($_[0] =~ /${a}IO$z/) ? $_[0]
: ($_[0] =~ /${a}GLOB$z/)   ? $_[0]
: croak "unknown data type $_[0] $ref";

--$DEPTH 
and $SEEN{$_} = ref($rval)
or  $SEEN = (); 

$ref !~ /^(HASH|ARRAY|SCALAR|GLOB|FORMAT|CODE|Regexp|REF|IO)$/ 
and bless $r, $ref
or  $r;
}




Re: RFC 67 (v1) Deep Copying, aka, cloning around.

2000-08-08 Thread Uri Guttman

 "GG" == Garrett Goebel [EMAIL PROTECTED] writes:

  GG Oops, my circular ref code is/was screwy...

   and $SEEN{$_} = $rval
   or  $SEEN = (); 

that last line looks screwy too! :-) assigning an empty list to a scalar? i
think you meant to assign to %SEEN.

but why reinvent the wheel with this code? we have modules which do
close to this now, and we have talked about using the GC traverse engine
as well.

uri

-- 
Uri Guttman  -  [EMAIL PROTECTED]  --  http://www.sysarch.com
SYStems ARCHitecture, Software Engineering, Perl, Internet, UNIX Consulting
The Perl Books Page  ---  http://www.sysarch.com/cgi-bin/perl_books
The Best Search Engine on the Net  --  http://www.northernlight.com



RE: RFC 67 (v1) Deep Copying, aka, cloning around.

2000-08-08 Thread Peter Scott

At 04:17 PM 8/8/00 -0500, Garrett Goebel wrote:
Here's a version of my own kludgey deep copy. -Updated to use our mythical
-CLONE method, and watch for circular references...

Great stuff, I've put it in v2.

[snip]
: /^CODE$/   ? $_[0]# " (B::Deparse)
[snip]
I would like deep copying to include copying CODE. It would be useful for
implementing object methods...

Why would it be necessary to deep copy a CODE reference?

  =head2 Filehandles
 
  If Cclone encounters an CIO::Handle, its default behavior
  will be to  make a copy of the filehandle (debatable: perhaps
  the default should be to throw an exception) unless a CCALLBACK
  function was specified

Doesn't this fall under $obj-CLONE?

IO::Handle appears to be what the builtin filehandles are these days (I'm 
trying to keep up; IO::Handle is mentioned in Camel III under ref(), but 
5.6.0 filehandles still say GLOB - hmm, mebbe IO::Handle is just for 
sockets...).  Either way, yes, CLONE would or could be a method of the 
IO::Handle class but I wanted to make it explicit.

Speaking of UNIVERSAL::CLONE is it really more complicated than a special
case of the above dcopy subroutine?

Nope, it would indeed call that subroutine and not much else.  But I think 
dcopy/clone will end up being an internal, not Perl code.

--
Peter Scott
Pacific Systems Design Technologies




Re: RFC 67 (v1) Deep Copying, aka, cloning around.

2000-08-08 Thread Damian Conway

=head1 TITLE

Deep Copying, aka, cloning around.


The CCALLBACK is an optional function to be called if Cclone
encounters a filehandle.

...or anything else it doesn't know how to handle.
   

If Cclone encounters a tied variable, it will call the CCLONE
method...

...of the underlying implementation object...
   
or fall back to CUNIVERSAL::CLONE. 
   

=head1 REFERENCES
   

The Storable and Data::Dumper modules



Re: RFC 67 (v1) Deep Copying, aka, cloning around.

2000-08-08 Thread Uri Guttman


wacko idea:

combine a generic data tree traverse engine with damian's switch op.

you pass this new smart traverse a ref and it will scan the tree. at
every node it sees, it can call callbacks or methods. it can do the
callbacks in pre, in or post ordering to get useful effects. if a node
is an object, the optional method can be called (e.g. CLONE).

each node could also be handled by a switch on its type.

so this traverse engine could be shared by GC, clone, Data::Dumper,
Storable, etc.

just musing,

uri

-- 
Uri Guttman  -  [EMAIL PROTECTED]  --  http://www.sysarch.com
SYStems ARCHitecture, Software Engineering, Perl, Internet, UNIX Consulting
The Perl Books Page  ---  http://www.sysarch.com/cgi-bin/perl_books
The Best Search Engine on the Net  --  http://www.northernlight.com



Re: RFC 67 (v1) Deep Copying, aka, cloning around.

2000-08-08 Thread Peter Scott

At 06:10 PM 8/8/00 -0400, Uri Guttman wrote:

wacko idea:

combine a generic data tree traverse engine with damian's switch op.

you pass this new smart traverse a ref and it will scan the tree. at
every node it sees, it can call callbacks or methods. it can do the
callbacks in pre, in or post ordering to get useful effects. if a node
is an object, the optional method can be called (e.g. CLONE).

each node could also be handled by a switch on its type.

so this traverse engine could be shared by GC, clone, Data::Dumper,
Storable, etc.

I like it.

Can you tell me what semantics you use with something like this to get 
behavior like clone's, where the reult of a node depends on the results of 
other nodes?  Whether they've been visited already or not, how do you 
parcel all the results of, say, a ref-to-array together?

--
Peter Scott
Pacific Systems Design Technologies