Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Turning a datafile into a data structure

by ase (Monk)
on Jun 30, 2000 at 15:13 UTC ( [id://20579]=note: print w/replies, xml ) Need Help??


in reply to Turning a datafile into a data structure

I agree with Dave that Parse::RecDescent could be a good way to do it. If you want to "roll your own" though, you could do something like:
#!/usr/bin/perl -w use strict; package Item; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; bless ($self, $class); return $self; } sub add_attribute { my $self = shift; my ($key,$value) = @_; $self->{$key} = $value; } 1; #included in case Item becomes a real Module someday. package Section; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; $self->{Items} = []; bless ($self, $class); return $self; } sub add_attribute { my $self = shift; my ($key,$value) = @_; $self->{$key} = $value; } sub add_item { my $self = shift; my $item = Item->new(); push @{$self->{Items}},$item; return $item; } 1; #Ditto package UberObject; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = []; bless ($self, $class); return $self; } sub add_section { my $self = shift; my $section = Section->new(); push @$self,$section; return $section; } 1; #again package Main; use Data::Dumper; my $uo = new UberObject(); my ($section,$item) = (undef,undef); while (<>) { #dammit Jim, parse the data already! if (/begin_section/) { $section = $uo->add_section(); } elsif (/end_section/) { undef $section; } elsif (/begin_item/) { $item = $section->add_item(); } elsif (/end_item/) { undef $item; } elsif (/=/) { if (defined($item)) { $item->add_attribute(split(/=/)); } elsif (defined($section)) { $section->add_attribute(split(/=/)); } else { die "Bad attribute at line $."; } } } #probably should do something interesting ..... # .... nah Just Dump it all! my $d=Data::Dumper->new([$uo],['UberObject']); $d->Indent(1); print $d->Dump();

When tested with a file that contains:
begin_section name=section1 type=section_type1 begin_item name=item1 desc=item_description1 link=item_link1 end_item begin_item name=item2 desc=item_description2 link=item_link2 end_item end_section begin_section name=section2 type=section_type2 begin_item name=item21 desc=item_description21 link=item_link21 end_item begin_item name=item22 desc=item_description22 link=item_link22 end_item end_section

yields:
"The correct thing" (Exercise left to reader)
You may also consider massaging the data (or writing a converter) to XML and use XML::Parser which can also be used in an OOish way..
Note: As the last poster mentioned while I was busy typing, Error checking = Good, and I don't do enough of it in my example... another excersize left to reader.
Hope that helps,
-ase

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (5)
As of 2024-03-29 14:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found