Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

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

by frozenwithjoy (Priest)
on Jun 12, 2013 at 21:46 UTC ( [id://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.

Replies are listed 'Best First'.
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.
      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)

      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.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-04-23 15:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found