tags:

views:

556

answers:

2

I want to check if parameter $PGkey is equal to a key with the same name inside a hash table. Further, I want to do it in a format as close to this as possible:

while(<PARAdef>) {
    my($PGkey, $PGval) = split /\s+=\s+/;
    if($PGkey == $hash{$PGkey}) {
        print PARAnew "$PGkey = $hash{$PGkey}->[$id]\n";
    } else {
        print PARAnew "$PGkey = $PGval\n";
    }
}

Is there a simple way to do it?

+2  A: 

Using the conditional operator lets you factor out the common code in that if/else statement:

while ( <PARAdef> ) {
    chomp;
    my ($PGkey, $PGval) = split /\s+=\s+/;
    print "$PGkey = ",
        $PGval eq $hash{$PGkey}[$id] ? $hash{$PGkey}[$id] : $PGval, "\n";
}

Or if you just misstated the problem and really want to use $hash{$PGkey}[$id] if $hash{$PGkey} exists and fall back to $PGval if it doesn't, then you can say

while ( <PARAdef> ) {
    chomp;
    my ($PGkey, $PGval) = split /\s+=\s+/;
    print "$PGkey = ",
        $PGkey ne "def" and exists $hash{$PGkey} ?
            $hash{$PGkey}[$id] : $PGval, "\n";
}

A quick note, you seem to be using the old bareword style filehandles. The new (if ten years old can be considered new) lexical filehandles are superior in every way:

open my $PARAdef, "<", $filename
    or die "could not open $filename: $!";
Chas. Owens
Please, sir, stop calling the conditional operator "the ternary operator". I beg of you.
chaos
No, Chas, please don't.
innaM
@Manni: Learn what "ternary operator" means, please. It means an operator that takes three arguments. `?:` is not the only possible operator that takes three arguments. What it is legitimately defined by is the fact that it defines a conditional alternation, which is why to call it by its correct name, the conditional operator.
chaos
Thanks Chas, the second answer seems to work fine. Even though it create an empty line between each of the unmatched keys. The file handle I used: open(PARAdef, "<$para_dir/$para_def_file") or die $!; I'll take your note to my mind - THANKS !
YoDar
Can I add to your 2 answer somehow a case that if $PGval == "def" then print PARAdef "$PGkey = $PGval" ?
YoDar
I know what "ternary operator" means. It may well be a very bad name, but it's its name.
innaM
@chaos You have a good point. I will change it because it will make finding it in perlop easier. I could have sworn it was named the ternary in ANSI C (which is where I came from initially), but even in "The C Programming Language" it is referred to as the "conditional expresssion".
Chas. Owens
@Manni Take a look at http://perldoc.perl.org/perlop.html#Conditional-Operator, it surprised me as well, but hey, I got my learn-one-new-thing-a-day out of the way early today.
Chas. Owens
@YoDar I assumed you wanted that behavior, the reason the blank lines are showing up is $_ is set to the line that was read from PARAdef (including its line-ending-character(s)). Your split does not affect this, so $PGval has a "\n" on its end. The solution is to use chomp to removed the line-ending-character(s) before the split occurs. I have modified the answer to reflect this
Chas. Owens
+14  A: 

Your question's kind of obscure, but the way to check for hash key existence is:

exists $hash{$key}
chaos