lalala53__
lalala53__

Reputation: 25

Reading input file and creating new hash

My input files have percentage exposures and I read in only the highest value.

I keep getting errors

odd number of elements in anonymous hash

and

Can't use string as an ARRAY ref while "strict refs" in use

I tried forcing the numbers to be read in as integers but fell flat. Any advice? I'd like to create a hash with key and highest value.

    while ( <$DATA_FILE> ) {

        chomp;
        my @line_values = split( /,/, $_ );
        my $state_id    = $line_values[0];

        # skip header row
        next if ( $state_id eq $HEADER_VALUE );

        for ( @line_values ) {
            tr/%%//d
        };

        # assign data used as hash keys to variables
        my $var1 = int( $line_values[1] );
        my $var2 = int( $line_values[2] );

        if ( $var1 > $var2 ) {
            %report_data = ( { $state_id } => { \@$var1 } )
        }
        else {
            %report_data = ( { $state_id } => { \@$var2 } )
        }

    } # end while

    print \%report_data;

    # close file
    close( $DATA_FILE ) || printf( STDERR "Failed to close $file_path\n" );
}

Upvotes: 0

Views: 300

Answers (2)

Borodin
Borodin

Reputation: 126722

It's hard to be sure without any indication of what the input and expected output should be, but at a guess your if blocks should look like this

if ( $var1 > $var2 ) {
    $report_data{$state_id} = $var1;
}
else {
    $report_data{$state_id} = $var2;
}

or, more simply

$report_data{$state_id} = $var1 > $var2 ? $var1 : $var2;

Upvotes: 1

janh
janh

Reputation: 2972

This line is the culprit:

%report_data = ({$state_id} => {\@$var1})

{ } creates a hashref. You are doing two weird things in this line: use a hashref with a single key ($state_id) as the key in %report_data and a hashref with a single key (\@$var1, which tries to derefence the scalar $var1 and use it in array context (@$var1) and then tries to turn that into a reference again (I'm confused, no wonder the interpreter is as well) ). That'd make more sense as

%report_data = ($state_id => $var1);

But that would reset the hash %report_data for every line you read. What you want is to just set the key of that hash, so first, define the variable before the loop:

my %report_data = ();

and in your while loop, just set a key to a value:

$report_data{ $state_id } = $var1; # or $var2

Finally, you are trying to print a reference to the hash, which makes little sense. I'd suggest a simple loop:

for my $key (keys %report_data) {
    print $key . " = " . $report_data{ $key } . "\n";
}

This iterates over all the keys in the hash and then prints them with their values, and looks easy to read and understand, I hope.

In general: don't try to use references unless you know how they work. They are not a magic bullet that you fire at your code and all the problems go poof; quite the opposite, they can become that painful bullet that ends up in your own foot. It's good to learn about references, though, because you will need them when you advance and work more with Perl. perlreftut is a good place to start.

Upvotes: 0

Related Questions