Parse data structure

Discussion in 'Perl Misc' started by Davidcollins001@gmail.com, Jul 16, 2006.

  1. Guest

    I am looking to parse data into a complex structure of hashes and
    arrays. I have been reading the data structures cookbook on the CPAN
    website
    (http://search.cpan.org/~nwclark/perl-5.8.7/pod/perldsc.pod#MORE_ELABORATE_RECORDS).
    At the bottom they say that it is sometimes easier to have the file as
    the data structure that would be used to create the structure in perl.

    I was wondering how to do this? I have been playing around trying to
    learn how to use complex structures, but I can't figure out how to get
    perl to parse code into a hash? I did initially think of placing the
    data structure in a file and setting the hash equal to it, but that
    doesn't work. am I thinking too simplistic?

    This is my data structure that I am playing around with in a separate
    file:

    may => [
    [2,'train',20.00, 'expensive'],
    [6,'train',15],
    [19,'car',18,'best way']
    ],
    june => [
    [5,'car',2.00],
    [9,'train',1],
    [19,'cat',18,'best way']
    ],
    july => [
    [14,'plane',100],
    [23,'boat',20]
    ],


    And this is the code I have to read and print it out:


    ## read above from file into hash
    open(DATA, "<$file");
    my %HoLoL=<DATA>;
    close(DATA);


    ## print each element separately
    foreach my $date ( keys %HoLoL )
    {
    print "$date";
    for(my $i=0; $i<($#{@{$HoLoL{$date}}}+1); $i++)
    {
    for(my $j=0; $j<($#{ $HoLoL{$date} [$i] }+1); $j++)
    {
    print "\t ${ $HoLoL{$date} [$i]}[$j] ";
    }
    print "\n";
    }
    }
    print "\n";


    (I know I can print it out easier and probably quicker with one less
    loop at least, I just wanted to know how to get to each element.)

    Thanks in advance
     
    , Jul 16, 2006
    #1
    1. Advertising

  2. Bob Walton Guest

    wrote:
    > I am looking to parse data into a complex structure of hashes and
    > arrays. I have been reading the data structures cookbook on the CPAN
    > website
    > (http://search.cpan.org/~nwclark/perl-5.8.7/pod/perldsc.pod#MORE_ELABORATE_RECORDS).
    > At the bottom they say that it is sometimes easier to have the file as
    > the data structure that would be used to create the structure in perl.
    >
    > I was wondering how to do this? I have been playing around trying to
    > learn how to use complex structures, but I can't figure out how to get
    > perl to parse code into a hash? I did initially think of placing the
    > data structure in a file and setting the hash equal to it, but that
    > doesn't work. am I thinking too simplistic?
    >
    > This is my data structure that I am playing around with in a separate
    > file:
    >
    > may => [
    > [2,'train',20.00, 'expensive'],
    > [6,'train',15],
    > [19,'car',18,'best way']
    > ],
    > june => [
    > [5,'car',2.00],
    > [9,'train',1],
    > [19,'cat',18,'best way']
    > ],
    > july => [
    > [14,'plane',100],
    > [23,'boat',20]
    > ],
    >
    >
    > And this is the code I have to read and print it out:
    >
    >
    > ## read above from file into hash
    > open(DATA, "<$file");
    > my %HoLoL=<DATA>;
    > close(DATA);
    >
    >
    > ## print each element separately
    > foreach my $date ( keys %HoLoL )
    > {
    > print "$date";
    > for(my $i=0; $i<($#{@{$HoLoL{$date}}}+1); $i++)
    > {
    > for(my $j=0; $j<($#{ $HoLoL{$date} [$i] }+1); $j++)
    > {
    > print "\t ${ $HoLoL{$date} [$i]}[$j] ";
    > }
    > print "\n";
    > }
    > }
    > print "\n";
    >
    >
    > (I know I can print it out easier and probably quicker with one less
    > loop at least, I just wanted to know how to get to each element.)
    >
    > Thanks in advance
    >


    Well, if you want to make your data files be Perl code, make it
    valid Perl, something like:

    $HoLoL={
    may => [
    [2,'train',20.00, 'expensive'],
    [6,'train',15],
    [19,'car',18,'best way']
    ],
    june => [
    [5,'car',2.00],
    [9,'train',1],
    [19,'cat',18,'best way']
    ],
    july => [
    [14,'plane',100],
    [23,'boat',20]
    ],
    };

    Then you can write a Perl program to execute this data file as
    follows, taking advantage of an already-written module to print
    the data structure (which module, incidentally, generates valid
    Perl code):

    use strict;
    use warnings;
    our $HoLoL;
    do 'junk566.txt';
    use Data::Dumper;
    print Dumper($HoLoL);

    When run, this generates:

    D:\junk>perl junk566.pl
    $VAR1 = {
    'june' => [
    [
    5,
    'car',
    '2'
    ],
    [
    9,
    'train',
    1
    ],
    [
    19,
    'cat',
    18,
    'best way'
    ]
    ],
    'may' => [
    [
    2,
    'train',
    '20',
    'expensive'
    ],
    [
    6,
    'train',
    15
    ],
    [
    19,
    'car',
    18,
    'best way'
    ]
    ],
    'july' => [
    [
    14,
    'plane',
    100
    ],
    [
    23,
    'boat',
    20
    ]
    ]
    };

    D:\junk>

    HTH.
    --
    Bob Walton
    Email: http://bwalton.com/cgi-bin/emailbob.pl
     
    Bob Walton, Jul 16, 2006
    #2
    1. Advertising

  3. Guest

    Hi Bob,

    That is exactly what I was after. Thanks :)
     
    , Jul 16, 2006
    #3
  4. Ben Morrow Guest

    Quoth Bob Walton <>:
    > wrote:
    > > This is my data structure that I am playing around with in a separate
    > > file:
    > >
    > > may => [
    > > [2,'train',20.00, 'expensive'],
    > > [6,'train',15],
    > > [19,'car',18,'best way']
    > > ],
    > > june => [
    > > [5,'car',2.00],
    > > [9,'train',1],
    > > [19,'cat',18,'best way']
    > > ],
    > > july => [
    > > [14,'plane',100],
    > > [23,'boat',20]
    > > ],

    >
    > Well, if you want to make your data files be Perl code, make it
    > valid Perl, something like:
    >
    > $HoLoL={
    > may => [
    > [2,'train',20.00, 'expensive'],
    > [6,'train',15],
    > [19,'car',18,'best way']
    > ],
    > june => [
    > [5,'car',2.00],
    > [9,'train',1],
    > [19,'cat',18,'best way']
    > ],
    > july => [
    > [14,'plane',100],
    > [23,'boat',20]
    > ],
    > };
    >
    > Then you can write a Perl program to execute this data file as
    > follows, taking advantage of an already-written module to print
    > the data structure (which module, incidentally, generates valid
    > Perl code):
    >
    > use strict;
    > use warnings;
    > our $HoLoL;
    > do 'junk566.txt';
    > use Data::Dumper;
    > print Dumper($HoLoL);


    You can also avoid having to have the name of the variable in the file
    (generally a good idea: firstly data files shouldn't need to know what
    variables in the program they will be read into; secondly it means you
    don't need to use a global, which is always a good thing):

    #!/usr/bin/perl -l

    use strict;
    use warnings;
    use Data::Dump qw/dump/; # I prefer this to Data::Dumper

    my $HoLoL = { do "junk566.txt" };
    print dump $HoLoL;

    __END__

    Note that this technique, while powerful, is not terribly safe. It's
    basically equivalent to string eval, so all the caveats of that apply.
    You don't get very clear error messages if the file contains syntax
    errors, and dealing with this is somewhat tricky. More importantly, it
    is possible to muck up anything in the program with an incorrect or
    malicious data file, which leads to difficult-to-find bugs and security
    holes (where that is important).

    For an alternative way of creating data files which mimic the Perl
    structures they read into, try YAML. For example:

    travel.yml:
    july:
    -
    - 14
    - plane
    - 100
    -
    - 23
    - boat
    - 20
    june:
    -
    - 5
    - car
    - 2
    -
    - 9
    - train
    - 1
    -
    - 19
    - cat
    - 18
    - best way
    may:
    -
    - 2
    - train
    - 20
    - expensive
    -
    - 6
    - train
    - 15
    -
    - 19
    - car
    - 18
    - best way

    Then write something like:

    #!/usr/bin/perl -l

    use strict;
    use warnings;
    use YAML;
    use Data::Dump qw/dump/;

    my $h = YAML::LoadFile 'travel.yml';
    print dump $h;

    __END__

    It is possible to write YAML in a more Perlish style, like

    {
    may: [
    [2, train, expensive],
    [6, train, 15]
    ]
    }

    but YAML.pm currently doesn't seem to load these. YAML::Syck (which is
    based on libsyck, written in C) does, but I can't seem to make it emit
    them, if that's a concern for you. See
    http://yaml4r.sourceforge.net/cookbook/ for an intro: don't worry that
    it's for Ruby, most of the syntax is the same as Perl.

    Ben

    --
    Like all men in Babylon I have been a proconsul; like all, a slave ... During
    one lunar year, I have been declared invisible; I shrieked and was not heard,
    I stole my bread and was not decapitated.
    ~ ~ Jorge Luis Borges, 'The Babylon Lottery'
     
    Ben Morrow, Jul 17, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    19
    Views:
    1,136
    Daniel Vallstrom
    Mar 15, 2005
  2. Viegas
    Replies:
    1
    Views:
    364
    travishein
    Aug 22, 2008
  3. Barry Schwarz

    Re: How to parse this string into a list structure?

    Barry Schwarz, Nov 7, 2008, in forum: C Programming
    Replies:
    0
    Views:
    372
    Barry Schwarz
    Nov 7, 2008
  4. A
    Replies:
    27
    Views:
    1,606
    Jorgen Grahn
    Apr 17, 2011
  5. 7stud --

    optparse: parse v. parse! ??

    7stud --, Feb 20, 2008, in forum: Ruby
    Replies:
    3
    Views:
    190
    7stud --
    Feb 20, 2008
Loading...

Share This Page