in reply to How to change referent of lexical reference?

If I understand you, you want to be able to freeze two (or more) references to the same data or datastructure and when you thaw them, have both references again refer to a single copy of the referent, rather than two separate copies.

For this to happen, you need to ensure that you pass both (all) of the data to Storable::freeze() at the same time. This is the only way that it will be able to determine that the references do indeed refer to the same data.

#! perl -slw use strict; use Data::Dumper; use Storable qw[freeze thaw]; my $hashref = { my=>'data' }; my $refA = \$hashref; my $refB = \$hashref; { my @frozen = map{ freeze $_ } $refA, $refB; my( $refA_thawed, $refB_thawed ) = map{ thaw $_ } @frozen; print Dumper $refA_thawed, $refB_thawed; } { my @data = ( $refA, $refB ); my $frozen = freeze \@data; my $thawed = thaw $frozen; my ($refA, $refB) = @$thawed; print Dumper $refA, $refB; } __END__ $VAR1 = \{ 'my' => 'data' }; $VAR2 = \{ 'my' => 'data' }; $VAR1 = \{ 'my' => 'data' }; $VAR2 = $VAR1;

In the first anon. block, the two references are frozen in separate calls to freeze() and thaw(), and so Storable has no way to recognise that they refer to the same data, and when they are thawed, they are pointed at separate copies of the data.

However, in the second block, the two references are passed to freeze() during the same call. This is achieved by simply wrapping them into a common data structure (@data). This way, you are giving Storable the opportunity to recognise that the both references refer to the same data, and it does the appropriate thing accordingly.

Now when the data is thawed(), the resultant references again point to a single copy of the referent.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
If I understand your problem, I can solve it! Of course, the same can be said for you.

Replies are listed 'Best First'.
Re: Re: How to change referent of lexical reference?
by autarch (Hermit) on Sep 23, 2003 at 03:43 UTC
    If I understand you, you want to be able to freeze two (or more) references to the same data or datastructure and when you thaw them, have both references again refer to a single copy of the referent, rather than two separate copies.

    No, that's not what I want. I want to be able to serialize an arbitrary data structure, and then every time it's thawed I want to check if an existing data structure in memory matches the thawed one, and silently tell Storable to simply use the existing one instead.

    I have no control over when or how things might be frozen, so your solution, while interesting, isn't really relevant.

      Sorry about that, though if your original question had been stated as clearly as here, then it might have saved a few false impressions:)

      The best suggestion I can make is that you keep a hash, with frozen copies of the in-memory datastructures that might match as the keys, and a reference to them as the values.

      When you import a frozen datastructure, you then just look it up in the hash and if you find a match, set the pointer to the new one to the value from the hash, and there would be no need (or point) in asking Storable to thaw the inbound structure. If not, just thaw() as normal.

      This would mean maintaining the frozen copies as the get modified, but this could be easily done by tieing the structures that make up each compound structure, and updating the frozen copy, cash hash on STORE.

      This arrangment would make for fast isolation of matching structures at the expense of the overhead of re-freezing when elements of the structure are updated.

      If you really wanted to trim that overhead, you could start playing games with arrays of lvalue refs into the frozen copy and overwrite individual fields, packing the data yourself, but this would require some effort to set up for the general case and you'll probably consider that overkill.


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      If I understand your problem, I can solve it! Of course, the same can be said for you.

        The whole point of doing this is so that people who use this module can freeze and thaw objects and not know what weirdness is going on in the background.