Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Need help from the esteemed monks on scoping/hashes

by garbage777 (Acolyte)
on Jun 05, 2006 at 16:49 UTC ( #553645=perlquestion: print w/ replies, xml ) Need Help??
garbage777 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
This is my first posting and I am relatively new to Perl. Hence please excuse if I failed to follow any posting rules.

I have a text file called "top.spef" that has the following lines -

*NAME_MAP *1 ab *2 abc *3 abcd *4 def *5 ghi *6 klm *7 mno *8 kji *9 ips *10 dlm *PORTS *D_NET *2 25 *D_NET *3 16 *D_NET *5 8 *D_NET *9 3

Here is what I want to do -

1. I want to remove "*" wherever it occurs,

2. I want to store the lines in between "NAME_MAP" and "PORTS" into a hash.

3. I want to replace numbers 2, 3, 5 and 9 in second column in lines that contain "D_NET" with the corresponding values of keys 2, 3, 5 and 9 from hash in step#2 above .

In order to do this, I wrote a small script as below -
#!/usr/bin/perl #use strict; use warnings; open(IHF, "<", "top.spef"); while( <IHF> ) { my @keys; my ($n, $k1); my %nets; my @net; my $item; next if (/^\n/); s/\*//g; s/^\s//g; s/\//:/g; ### Here we store the lines between the lines ### NAME_MAP and PORT into a hash called %mapping" ### and print the key,value pairs if (/NAME_MAP/ .. /PORTS/) { next if (/NAME_MAP/); next if (/PORTS/); %mapping = split; @keys = sort keys %mapping; foreach $k1 (sort keys %mapping) { print "$k1 = $mapping{$k1}\n"; } } if (/D_NET/) { my @anet = split; %nets = ($anet[1] , $anet[0]); for $n (sort keys %nets) { print "$mapping{$n}\n"; } } }
When I execute this code I get the following error -
Use of uninitialized value in concatenation (.) or string at ./mapping +.pl line 39, <IHF> line 23

I am assuming this error is issued by Perl because probably the hash %mapping scope may be not visible in the below part of the code -
if (/D_NET/) { my @anet = split; %nets = ($anet[1] , $anet[0]); for $n (sort keys %nets) { print "$mapping{$n}\n"; } }
Can you kindly suggest me what I am doing wrong and how to fix this problem ?
I very much appreciate all your help in advance.


Best Regards,
Dan

Comment on Need help from the esteemed monks on scoping/hashes
Select or Download Code
Re: Need help from the esteemed monks on scoping/hashes
by dragonchild (Archbishop) on Jun 05, 2006 at 16:58 UTC
    Uncomment 'use strict;', fix those errors, and your problem will be self-evident.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      Hi Dragonchild,
      I uncommented "use strict;" and executed the script. It complained about -

      Global symbol "%mapping" requires explicit package name at ./t line 26 +. Global symbol "%mapping" requires explicit package name at ./t line 27 +. Global symbol "%mapping" requires explicit package name at ./t line 30 +. Global symbol "%mapping" requires explicit package name at ./t line 31 +. Global symbol "%mapping" requires explicit package name at ./t line 39 +. Execution of ./t aborted due to compilation errors.


      Therefore I added "our %mapping;" in the script right after the "while(<IHF>) {" line and saved the script into a file called "t.pl". Now I get -
      Use of uninitialized value in concatenation (.) or string at ./t.pl li +ne 40, <IHF> line 233.


      I checked line 40 in the script. That line is -
      print "$mapping{$n}\n";

      Any suggestions? Thank you very much in advance.
      Best Regards,
      Dan
        You're accessing $mapping{$anet[0]} - did you ever assign to that key? Doesn't look like it . . .

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: Need help from the esteemed monks on scoping/hashes
by ioannis (Priest) on Jun 05, 2006 at 20:50 UTC
    The statement %mapping = split; ensures that the hash is re-initialized with only one key; yet, the for() loop wants to print the value of more than one key as it loops through print $mapping{$n} .
Re: Need help from the esteemed monks on scoping/hashes
by jwkrahn (Monsignor) on Jun 05, 2006 at 21:39 UTC
    Hi Dan,

    You should enable both strict and warnings pragmas.

    You should verify that the file opened correctly before trying to use the filehandle.

    You have all the variables declared inside the while loop so they are created anew each time a line is read from the file.

    This may do what you want:

    #!/usr/bin/perl use strict; use warnings; open IHF, '<', 'top.spef' or die "Cannot open 'top.spef' $!"; my %mapping; while ( <IHF> ) { tr/*//d; my @fields = split; if ( /NAME_MAP/ .. /PORTS/ ) { redo if /PORTS/; next unless @fields == 2; $mapping{ $fields[ 0 ] } = $fields[ 1 ]; } if ( /PORTS/ .. eof ) { next unless /D_NET/ and @fields == 3; print "$fields[0] $mapping{$fields[1]} $fields[2]\n"; } } __END__

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2014-11-26 20:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (173 votes), past polls