Friday, March 4, 2011

What does this Perl conditional do?

Hello,

I'm trying to understand a particular Perl code from vcake. Usually I find my way around in Perl but the following statement baffles me. I suspect that this is simply an error but I'm not completely sure. The statement is:

foreach my $seq (keys %$set) {
    if( (defined $set->{$seq}) and (my $numReads >= ($coverage)) ) {
        do something;
    }
    ...
}

$coverage has been defined at the beginning of the file as a scalar integer (e.g. 10) and is never again written to. $numReads is only used in the line above, nowhere else!

$set, on the other hand, is modified inside the loop so the first part of the condition makes perfect sense. What I don't understand is the second part because as I see it, this will always evaluate to the same value and I don't understand the significance of $numReads or >= here. Can someone please enlighten me? Are there perhaps invisible automatic variables involved?

From stackoverflow
  • my $numReads means: Create a new local variable within the context of the foreach loop. Its initial value is undef, which in numerical context is treated as 0. So the code reads:

    if ((...) and (0 >= ($coverage)) ) {
    }
    

    which means "do something" is never executed unless $coverage is set to 0 or less.

    If this was debug code, I'd assume that $coverage is used to enable/disable this statement.

    My guess is: You've found a bug.

    brian d foy : You mean "lexical" variable, because Perl unfortunately has a different meaning for "local" :)
    Dave Rolsky : Actually, the value of $numReads is undef, which in numeric context is treated as zero.
    Aaron Digulla : John: Thanks for the edit. :)
  • One might also note that unless $set is a reference to %set, or some other hash that mimics the structure of %set, then the line

    foreach my $seq (keys %set)
    

    Does not match the condition

    defined $set->{$seq}
    

    Since $set->{$seq} dereferences a hash ref, and %set is a hash. It is more likely that this is a second bug than it is that someone has instantiated both the hash %set and the scalar $set with a hashref.

    Konrad Rudolph : Thanks for noting – but this was simply a typo when I simplified the code for the posting. I've corrected it now: `$seq` is indeed a reference to a hash.

0 comments:

Post a Comment