Class-Eroot
view release on metacpan or search on metacpan
my %id = ();
while( @objs ){
$obj = shift @objs;
next if( ! defined $obj );
$class = "";
"$obj" =~ /^([^=]+)=/o && do { $class = $1 };
if( "$obj" =~ /([A-Z]+)\((0x[a-f0-9]+)\)$/o ){
($type,$ident) = ($1,$2);
next if( defined $id{$ident} );
$id{$ident}++;
push( @s, "end $ident" );
# Suspend the object.
eval { $obj->suspend } if( $class ne '' );
if( $type eq 'ARRAY' ){
if( @$obj ){
$self->StoreArray( $obj, $ident, \@s, \@objs );
}
}
elsif( $type eq 'HASH' ){
if( keys %$obj ){
$self->StoreHash( $obj, $ident, \@s, \@objs );
}
}
# The following also catches anything
# you thought was REF (REF is actually SCALAR^2).
elsif( $type eq 'SCALAR' ){
$self->StoreScalar( $obj, $ident, \@s, \@objs );
}
else{
die "Don't know how to handle $type $obj";
}
if( defined $roots->{$ident} ){
$n = $id2name->{$ident};
push( @s, "root $ident $n" );
$roots->{$ident} = undef;
}
push( @s, "object $ident $type $class" );
}
else{
warn "Eroot: Unable to recognize object $obj";
}
}
$self->DumpStack( \@s ) if $EROOT::DumpStack;
$self->WriteStack( $key, $name, \@s ) if $EROOT::WriteStack;
}
# Turn the stack into perl code.
# This will create a method named Continue in the EROOT class.
# This assumes that keys and values for the "objects" can be safely
# represented as text within single quotes.
#
## private
sub WriteStack {
my $self = shift;
my( $key, $name, $s ) = @_;
my $fh = (caller)[0] . "::$name";
my $i = @$s;
my( $type, @v, $v );
my( $junk, $word, $ident, $stuff );
my @roots = ();
my @keep = ();
my @keepwake = ();
my @wake = ();
my %wake = ();
my( $e1, $e2, $elem, $whack );
my @delayed = ();
open( $fh, ">$name" ) || do{
warn "Eroot: Cannot save objects, unable to write to file $name";
return;
};
print $fh "#KEY:$key\n";
print $fh "# Persistent objects\n";
print $fh "sub EROOT::Continue {\n";
print $fh " my \$self = shift;\n";
print $fh " my \%ref = ();\n";
print $fh " die \"These persistent objects (key=$key) do not belong to this application.\\n\"\n";
print $fh " if( \$self->{\'key\'} ne \'$key\' );\n";
while( $i-- > 0 ){
($junk, $word, $ident, $stuff) =
split( /^(\w+) ([^\s]+) ?/o, $s->[$i], 2 );
if( $word eq 'object' ){
@v = split( ' ', $stuff );
$e1 = $e2 = $type = $whack = '';
if( $v[0] eq 'ARRAY' ){
$e1 = "[";
$e2 = "]";
$type = " = []";
}
elsif( $v[0] eq 'HASH' ){
$e1 = "{\'";
$e2 = "\'}";
$type = " = {}";
}
elsif( $v[0] eq 'SCALAR' ){
$whack = "\\";
}
if( defined $v[1] ){
push( @wake, "$ident!\$self->Resume( \'$v[1]\', \$ref{\'$ident\'} );" );
$wake{$ident} = $#wake;
}
print $fh " {\n my \$x$type;\n";
}
elsif( $word eq 'root' ){
push( @keep, "\$self->Keep( \'$stuff\', \$ref{\'$ident\'} );" );
if( $wake{$ident} ){
push( @keepwake, "\$self->Resume( \'$v[1]\', \$ref{\'$ident\'} );" );
delete $wake{$ident};
}
}
elsif( $word eq 'end' ){
print $fh " \$ref{\'$ident\'} = $whack\$x;\n }\n";
}
elsif( $word eq 'ref' ){
($junk, @v) = split( /^\(([^)]*)\) /o, $stuff, 0 );
$elem = ($v[0] ne '') ? "->$e1$v[0]$e2" : "";
( run in 0.426 second using v1.01-cache-2.11-cpan-e93a5daba3e )