chrisyyy
chrisyyy

Reputation: 45

multiple if-else statement confusion perl

I'm having a problem with my if-else statement. Even if the $key I'm using matches the text in my if statement, the else statement I have at the bottom is also evaluated, so I'm getting multiple values for each $key, which is a problem. What am I doing wrong here?

my $key = $line[0];
if ($key eq 'this_setting') {
    my $counter1 = $counter + 1;
    my $counter2 = $counter + 2;
    $value = join(' ', @line[$counter1..$counter2]);                        
    $my_setting_hash{$key} = $value;
}
if ($key eq 'some_setting_abc') {
    my $counter1 = $counter + 1;
    my $counter2 = $counter + 2;
    $value = join(' ', @line[$counter1..$counter2]);
    $my_setting_hash{$key} = $value;
}
if ($key eq 'another_setting_123') {
    my $counter1 = $counter + 1;
    my $counter3 = $counter + 3;
    $value = join(' ', @line[$counter1..$counter3]);
    $my_setting_hash{$key} = $value;
}       
else {
    my $counter1 = $counter + 1;
    $value = $line[$counter1];
    $my_setting_hash{$key} = $value;
}

Why is this else statement not bypassed if one of my if statements is evaluated?

Upvotes: 3

Views: 112

Answers (3)

Miller
Miller

Reputation: 35198

As has already been pointed out, you need the keyword elsif

However, another solution is to put your special rules for each key into a hash and so that you can share code:

my %key_length = (
    this_setting        => 1,
    some_setting_abc    => 1,
    another_setting_123 => 2,
);

my $key = $line[0];

my $index_low = $counter + 1;
my $index_high = $index_low + ($key_length{$key} // 0);

$my_setting_hash{$key} = join ' ', @line[ $index_low .. $index_high ];

Upvotes: 6

Sinan Ünür
Sinan Ünür

Reputation: 118118

Let's say $key's value is 'some_setting_abc'. Your first if does not apply, but the second if does. The third if does not apply either but that one has an else therefore that is executed. As @TedHopp pointed out, you need a single if with chained elsifs and a final else instead.

However, I want to point out that there is a lot of duplication in your code. Life is simpler when you write code a bit more succinctly:

my $key = $line[0];
my $index = $counter + 1;

if (($key eq 'this_setting') or ($key eq 'some_setting_abc')) {
    $my_setting_hash{$key} = join ' ', @line[$index .. ($index + 1)];
}
elsif ($key eq 'another_setting_123') {
    $my_setting_hash{$key} = join ' ', @line[$index .. ($index + 2)];
}       
else {
    $my_setting_hash{$key} = $line[$index];
}

Upvotes: 4

Ted Hopp
Ted Hopp

Reputation: 234795

You need to chain them together with elsif:

my $key = $line[0];
if ($key eq 'this_setting') {
    my $counter1 = $counter + 1;
    my $counter2 = $counter + 2;
    $value = join(' ', @line[$counter1..$counter2]);                        
    $my_setting_hash{$key} = $value;
}
elsif ($key eq 'some_setting_abc') {
    my $counter1 = $counter + 1;
    my $counter2 = $counter + 2;
    $value = join(' ', @line[$counter1..$counter2]);
    $my_setting_hash{$key} = $value;
}
elsif ($key eq 'another_setting_123') {
    my $counter1 = $counter + 1;
    my $counter3 = $counter + 3;
    $value = join(' ', @line[$counter1..$counter3]);
    $my_setting_hash{$key} = $value;
}       
else {
    my $counter1 = $counter + 1;
    $value = $line[$counter1];
    $my_setting_hash{$key} = $value;
}

Otherwise, the first two if statements are independent of the third if/else statement.

Upvotes: 10

Related Questions