greatshots has asked for the wisdom of the Perl Monks concerning the following question:

monks,

opendir(SPR , "/apps/inst1/metrica/TechnologyPacks/ON-SITE/Nokia_S11.5 +/reportspr/") or die "$!"; while ( defined ( $file_name = readdir(SPR) ) ) { next if ( -d $file_name ); # removing . and .. open ( FH , "/apps/inst1/metrica/TechnologyPacks/ON-SITE/Nokia_S11 +.5/reportspr/$file_name" ) or die "$!"; $spr_hash{$file_name} = []; @$spr_hash{$file_name} = <FH>; } print Dumper [ %spr_hash ];
Output
$VAR1 = [ 'rep_vnz_gprs_performance_report_daily_spr.sql', [], 'rep_vnz_cchnwpossumreport2_spr.sql', [], 'rep_vnz_gprs_tbf_report_bh_spr.sql', [], 'rep_vfnz_weeklytrxblockingreport_spr.sql', [], 'rep_vnz_gprs_perf_report_daily_enhanced_spr.sql', [],
the file contents are not added in the value of a hash. what is the wrong in the code ?

Replies are listed 'Best First'.
Re: building a hash with filname and itscontents
by Errto (Vicar) on Oct 30, 2006 at 04:23 UTC
    The syntax you're using to access the array reference in the hash is incorrect. It should be
    @{$spr_hash{$file_name}}
    The extra braces are important. Otherwise what you've got is a single-element slice of the hash referenced by the scalar $spr_hash. Enabling use strict would have given you a hint that something was wrong by pointing out that you were referencing this undeclared scalar variable. Truthfully, though, you can write those two lines more simply as
    $spr_hash{$file_name} = [<FH>];
    and put the file contents right in the anonymous array. No need to initialize it with a blank array first.
Re: building a hash with filname and itscontents
by GrandFather (Saint) on Oct 30, 2006 at 04:22 UTC

    For a start it doesn't use strictures (use strict; use warnings).

    You may find changing

    @$spr_hash{$file_name} = <FH>;

    to

    @{$spr_hash{$file_name}} = <FH>;

    helps. The following sample script would have shown the problem more clearly:

    use strict; use warnings; use Data::Dumper; my $file_name = 'test.txt'; my %spr_hash; $spr_hash{$file_name} = []; @$spr_hash{$file_name} = qw(1 2 3); print Dumper [ %spr_hash ];

    DWIM is Perl's answer to Gödel
Re: building a hash with filname and itscontents
by jdporter (Paladin) on Oct 30, 2006 at 04:41 UTC

    Others have answered your immediate question, but I'd like to point out a couple things you could improve:

    1. You should close all the handles you open, and at the earliest possible time.
    2. print Dumper [ %spr_hash ] would probably be better written as print Dumper \%spr_hash.

    We're building the house of the future together.
Re: building a hash with filname and itscontents
by graff (Chancellor) on Oct 30, 2006 at 04:41 UTC
    As jesuashok points out, in order to assign an anonymous array as the value of  $spr_hash{$file_name} you have to put curlies around that, and put the "@" outside the open-curly. (You don't need to assign an empty array reference to it first.)

    I think you also need to include the path with the file name when doing the "-d" test, unless that path happens to be the current working directory when you run the script. (I'm assuming the directory you're reading could contain subdirectories.)

    Apart from that, why do you cast the hash into an anonymous array when passing it to Data::Dumper? (Just curious -- normally, I'd expect something like print Dumper( \%hash ); .)

    Did you consider slurping the file, to simplify the structure? (You can always do "split /\n/" as needed later on.)

    And don't you hate having to put in long string literals more than once? I do -- so much so that it's worth declaring another scalar:

    my %spr_hash; # you do use strict, don't you? my $path = "/apps/inst1/metrica/TechnologyPacks/ON-SITE/Nokia_S11.5/re +portspr"; opendir( D, $path ) or die "$path: $!"; while ( my $file = readdir( D )) { next if ( -d "$path/$file" ); open( F, "<", "$path/$file" ) or die "$path/$file: $!"; # @{$spr_hash{$file}} = <F>; # I'd rather slurp to a scalar: { local $/; $spr_hash{file} = <F>; } } print Dumper( \%spr_hash );
Re: building a hash with filname and itscontents
by jesuashok (Curate) on Oct 30, 2006 at 04:18 UTC

    opendir(SPR , "/apps/inst1/metrica/TechnologyPacks/ON-SITE/Nokia_S11.5 +/reportspr/") or die "$!"; while ( defined ( $file_name = readdir(SPR) ) ) { next if ( -d $file_name ); # removing . and .. open ( FH , "/apps/inst1/metrica/TechnologyPacks/ON-SITE/Nokia_S11 +.5/reportspr/$file_name" ) or die "$!"; $spr_hash{$file_name} = []; @{$spr_hash{$file_name}} = <FH>; } print Dumper [ %spr_hash ];
    modify it as above and try.