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?

chaos
  • 122,029
  • 33
  • 303
  • 309
YoDar
  • 377
  • 6
  • 15
  • 1
    What exactly is the problem? Is your code not working? – innaM Jul 27 '09 at 14:00
  • 1
    Are you sure "==" is the operator your want there? Are $PGkey and $hash{$PGkey} both numbers? If they're strings, use "eq" instead. – John Siracusa Jul 27 '09 at 14:33
  • John - yes, they are strings. Mani - you can see Chas answer, maybe it will light you my solved problem :) – YoDar Jul 27 '09 at 14:39
  • But only when you are online. – innaM Jul 27 '09 at 15:33
  • 1
    But decoding the question that the OP didn't ask is the SO advanced game, and really quite entertaining. I'm very proud of this one, for instance: http://stackoverflow.com/questions/1178141/why-does-my-jquery-click-handler-appear-to-run-multiple-times-for-some-of-its-tar/1178169 – chaos Jul 27 '09 at 18:11

2 Answers2

15

The way to check for hash key existence is:

exists $hash{$key}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
chaos
  • 122,029
  • 33
  • 303
  • 309
3

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
  • 64,182
  • 22
  • 135
  • 226
  • 3
    Please, sir, stop calling the conditional operator "the ternary operator". I beg of you. – chaos Jul 27 '09 at 14:26
  • 3
    @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 Jul 27 '09 at 14:31
  • 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 Jul 27 '09 at 14:32
  • Can I add to your 2 answer somehow a case that if $PGval == "def" then print PARAdef "$PGkey = $PGval" ? – YoDar Jul 27 '09 at 14:49
  • I know what "ternary operator" means. It may well be a very bad name, but it's its name. – innaM Jul 27 '09 at 15:04
  • 1
    @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 Jul 27 '09 at 15:10
  • 1
    @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 Jul 27 '09 at 15:11
  • @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 Jul 27 '09 at 15:18