Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: Storing/parsing perl data structure in/from a file

by frozenwithjoy (Curate)
on Jun 12, 2013 at 21:46 UTC ( #1038598=note: print w/ replies, xml ) Need Help??


in reply to Storing/parsing perl data structure in/from a file

If I'm understanding what you are going for, I'd use a hash of arrays of hashes. That way you keep all of the data and can easily find 'duplicated keys':

#!/usr/bin/env perl use strict; use warnings; use feature 'say'; use Data::Printer; my %hash = ( alpha1 => [ { beta => { gamma => 'theta', delta => 'lambda', } }, { beta => { gamma => 'zeta', } }, ], alpha2 => [ { beta => { gamma => 'theta', delta => 'lambda', } }, ], ); say "## Original state:"; check_duplication(); push @{ $hash{alpha2} }, { beta => { gamma => 'theta', } }; say "## After pushing another element onto 'alpha2':"; check_duplication(); sub check_duplication { for ( keys %hash ) { if ( scalar @{ $hash{$_} } > 1 ) { say "$_ has a duplicate."; } else { say "$_ is unique."; } } } p %hash;

OUTPUT:

{ alpha1 [ [0] { beta { delta "lambda", gamma "theta" } }, [1] { beta { gamma "zeta" } } ], alpha2 [ [0] { beta { delta "lambda", gamma "theta" } }, [1] { beta { gamma "theta" } } ] } ## Original state: alpha2 is unique. alpha1 has a duplicate. ## After pushing another element onto 'alpha2': alpha2 has a duplicate. alpha1 has a duplicate.


Comment on Re: Storing/parsing perl data structure in/from a file
Select or Download Code
Re^2: Storing/parsing perl data structure in/from a file
by Wilderness (Novice) on Jun 12, 2013 at 23:17 UTC
    Thanks for you answer ! My data structure is actually 6-7 levels deep and I got it to work with arrays of hashes of arrays of ... hashes. I want to know if it's possible to `do` a file partially, or open a file and manually parse each line and then `do` whatever part I want to. Anyways, I will work with arrays for now.
      You're welcome. What exactly do you mean when you say "`do` a file"?
        I mean, when I do `do $file`, Perl would read the entire data structure at once and overwrite hash keys with the last value it reads. I wish there was a way for me to traverse through the data structure (which Perl would be doing internally to be able to find key collisions) manually.
      Plz note: the data you posted is not a valid serialization of a HoH!

      The only way I see is to assign the data to a tied hash, which automatically reacts on collisions...of course all nested hashes need to be tied too.

      something like

      my $datastring =slurp $file; tie %h, "CollisionHash"; eval "\%h = $datastring"
      Not sure of this works, and I don't wanna trie to implement it for such a "unique" requirement...

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        As I feared (though it makes sense)

        tied_hashes do it with list assignments (they are sequential) but not with ano-hash assignment (they are precompiled, hence collisions are optimized)

        FWIW

        use strict; use warnings; use Data::Dump qw/pp/; package HoA; require Tie::Hash; our @ISA = qw(Tie::StdHash); sub STORE { my ($this,$key,$value) =@_; push @{$this->{$key}}, $value; } package main; my $data_str= do { local $/;<DATA>}; tie my %h, "HoA"; my $h=\%h; %h = eval "$data_str"; pp $h; %h = eval "%{ { $data_str } }"; pp $h; __DATA__ ( alpha => 1, alpha => 2 )

        shows

        { # tied HoA alpha => [1, 2], } { # tied HoA alpha => [2], }

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1038598]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2015-07-05 07:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls