----- Original Message ----- From: "Wiggins d'Anconia" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Cc: <[EMAIL PROTECTED]> Sent: Thursday, April 01, 2004 9:24 PM Subject: Re: Hash ref's of hash's
> [EMAIL PROTECTED] wrote: > > Hi all, > > I am trying to setup a hash who's values are referance to hash's. Data structure should look like this > > > > hash > > 1: > > setting 1 > > setting 2 > > 2: > > setting 1 > > setting 2 > > .... > > This does not look like a HoH, but a HoA. Reply no, this is HoH...perhaps beter diagramed as : NY => port 1 => setting 1 setting 2 CA => .... ..... > > > > > I would think it can be accomplished with following code, but when I try to print it out it only prints the last setting which it read. Any idea's ?? > > > > CODE: > > #!perl -w > > use strict; > > open RD, "input.txt"; > > Always check that open succeeded. > > open RD, "input.txt" or die "Can't open file: $!"; > > > > > my ( $field,$portsetting, $value, $port, $portnum, %digi, $debug ); > > $debug=0; > > > > Declaring all of your variables up front reduces the help that 'strict' > can provide and generally leads to more problems. It may be that $field > is getting reused because even though you are "emptying" it, this isn't > clear to me. Good point, I'll consider it > > > while ( <RD> ) { > > Let's dispense with $_ it adds confusion when we should be trying to be > explicit. Once you don't have to ask questions about references then > consider going back to it. This is a stylistic argument > > while (my $line = <RD>) { > > > if(m/^(port)\s\=\s(.*)$/i){$portnum=$2;$portnum++} > > > > Whitespace is our friend, why are we capturing a constant? Good point, I was debuging code and didn't remove it > > if ($line =~ m/^port\s=\s(.*)$/i) { > $portnum = $1; > } > > > $field = {}; > > $digi{$portnum} = $field; > > > > Double assignment? For clarity > > > m/^(.*)\s\=\s(.*)$/; > > If we are going to capture we should double check that the string is > formatted properly, put this into an if. > > if ($line =~ m/^(.*)\s=\s(.*)$/) { Agreed... > > There's no real need for the temp variables but if you want them that is > fine for readability. I need this so I can remove any '-' in a field 'porttitle', thats is why I do tr and create a new field TYPE. Perhaps this can be avoided with a beter regex. I do apoligize for nto providing example in my data...will append a new set to thread > > > $portsetting=$1; > > $value=$2; > > $field->{$portsetting}=$value; > > > > > print "setting $portsetting -> $digi{$portnum}{$portsetting}\n" if $debug; > > > > if($portsetting eq 'porttitle'){ > > $value =~ tr /-/ /; > > $value =~ m/^(\w+)\s+(\w+)/i; > > Again if you are going to run a match make sure it succeeds, especially > when capturing. As a side note your sample data did not contain this. > > > $field->{$portsetting}=$1; > > $field->{'type'}=$2; > > print "1:$digi{$portnum}{$portsetting}\t2:$digi{$portnum}{'type'}\n" if $debug; > > } > > > > } > > > > > > # print the whole thing > > foreach $port ( keys %digi ) { > > print "$port: { "; > > for $field ( keys %{ $digi{$port} } ) { > > print "$field=$digi{$port}{$field} "; > > } > > print "}\n"; > > } > > > > If this is just for debugging take a look at Data::Dumper it is much easier. > > > Sample DATA > > > > port = 0 > > bmanset = 0 > > benable = 1 > > uarttype = 0 > > baudrate = 9600 > > stopbits = 1 > > databits = 8 > > parity = 0 > > flowcontrol = 0 > > protocol = 1 > > port = 1 > > bmanset = 0 > > benable = 1 > > uarttype = 0 > > baudrate = 9600 > > stopbits = 1 > > databits = 8 > > parity = 0 > > flowcontrol = 0 > > protocol = 1 > > > > > > Essentially something is very awkward about all of that code, and it can > definitely be simplified by using better scoping. You should consider > reading, if you haven't already, > > perldoc perldsc > perldoc perllol > perldoc perlreftut > perldoc perlref > > Here is a stab, untested, > > #!/usr/local/bin/perl > use strict; > use warnings; > > > my %ports; > > > my $current_port = ''; > while (my $line = <DATA>) { > if ($line =~ /^port\s=\s(\d+)$/) { > $current_port = $1; > } > elsif ($line =~ /^(.*)\s=\s(.*)$/) { > die "Port not set" unless $current_port ne ''; > $ports{$current_port}->{$1} = $2; > } > else { > warn "Improperly formatted line: $line"; > } > } > > > use Data::Dumper; > print Dumper(\%ports); > > > __DATA__ > port = 0 > bmanset = 0 > benable = 1 > uarttype = 0 > baudrate = 9600 > stopbits = 1 > databits = 8 > parity = 0 > flowcontrol = 0 > protocol = 1 > port = 1 > bmanset = 0 > benable = 1 > uarttype = 0 > baudrate = 9600 > stopbits = 1 > databits = 8 > parity = 0 > flowcontrol = 0 > protocol = 1 > > -- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > <http://learn.perl.org/> <http://learn.perl.org/first-response> > > data to reflect porttitle field port = 17 bmanset = 0 benable = 1 uarttype = 0 baudrate = 9600 stopbits = 1 databits = 8 parity = 0 flowcontrol = 0 protocol = porttitle = ny1-SUN port = 18 bmanset = 0 benable = 1 uarttype = 0 baudrate = 9600 stopbits = 1 databits = 8 parity = 0 flowcontrol = 0 protocol = porttitle = ny2 -IBM port = 19 bmanset = 0 benable = 1 uarttype = 0 baudrate = 9600 stopbits = 1 databits = 8 parity = 0 flowcontrol = 0 protocol = porttitle = ny1 SUN- port = 20 bmanset = 0 benable = 1 uarttype = 0 baudrate = 9600 stopbits = 1 databits = 8 parity = 0 flowcontrol = 0 protocol = porttitle = ny1 SUN port = 21 bmanset = 0 benable = 1 uarttype = 0 baudrate = 9600 stopbits = 1 databits = 8 parity = 0 flowcontrol = 0 protocol = porttitle = ny1 -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>