Danwifi has asked for the wisdom of the Perl Monks concerning the following question:

Wise gurus, what in the heck does this code actually DO?

$v = ${$pairs{$ca}}[0]; if ($types{$ca}) { $v = 0 unless defined $v; OP: { $r &= $v < $cv, last OP if $co eq '<'; $r &= $v <= $cv, last OP if $co eq '<='; $r &= $v != $cv, last OP if $co eq '!='; $r &= $v >= $cv, last OP if $co eq '>='; $r &= $v > $cv, last OP if $co eq '>'; $r &= $v == $cv; } } else { $v = '' unless defined $v; OP: { $r &= $v lt $cv, last OP if $co eq '<'; $r &= $v le $cv, last OP if $co eq '<='; $r &= $v ne $cv, last OP if $co eq '!='; $r &= $v ge $cv, last OP if $co eq '>='; $r &= $v gt $cv, last OP if $co eq '>'; $r &= $v eq $cv; }




What is the OP: ? is that a label? Variable? I am new to PERL and I dont have a clue what this bit of code is actually doing, nor can I find anything like it out there.
thanks

20050121 Janitored by Corion: Added code tags

Retitled by davido.

Replies are listed 'Best First'.
Re: What does 'last OP;' do?
by ikegami (Patriarch) on Jan 21, 2005 at 21:12 UTC

    It is indeed a label. last OP will jump to the } of the block labeled OP.

    OP: { $r &= $v < $cv, last OP if $co eq '<'; $r &= $v <= $cv, last OP if $co eq '<='; $r &= $v != $cv, last OP if $co eq '!='; $r &= $v >= $cv, last OP if $co eq '>='; $r &= $v > $cv, last OP if $co eq '>'; $r &= $v == $cv; }

    is the same as

    if ($co eq '<' ) { $r &= $v < $cv; } elsif ($co eq '<=') { $r &= $v <= $cv; } elsif ($co eq '!=') { $r &= $v != $cv; } elsif ($co eq '>=') { $r &= $v >= $cv; } elsif ($co eq '>' ) { $r &= $v > $cv; } else { $r &= $v == $cv; }

      If you initialize %STR_OPS and %NUM_OPS as follows:

      # Do this once for efficiency. use vars qw(%NUM_OPS %STR_OPS); BEGIN { $NUM_OPS{$_} = eval "sub { \$_[0] $_ \$_[1] }" foreach (qw(< <= != >= > ==)); $STR_OPS{$_} = eval "sub { \$_[0] $_ \$_[1] }" foreach (qw(lt le ne ge gt eq)); }

      Then the snippet boils down to:

      $v = ${$pairs{$ca}}[0]; if ($types{$ca}) { $v = 0 unless defined $v; $op = $NUM_OPS{$co}; } else { $v = '' unless defined $v; $op = $STR_OPS{$co}; } die("Undefined operation $co.\n") unless $op; $r &= $op->($v, $cv);

      It's even more robust than the original.

        I would go further, and make a single array or hash containing all of %NUM_OPS and %STR_OPS. For example:

        BEGIN { $OPS{'num'}{$_} = eval "sub { \$_[0] $_ \$_[1] }" foreach (qw(< <= != >= > ==)); $OPS{'str'}{$_} = eval "sub { \$_[0] $_ \$_[1] }" foreach (qw(lt le ne ge gt eq)); } # ... and later ... $v = ${$pairs{$ca}}[0]; my $op_type = $types{$ca} ? 'num' : 'str'; my $op = $OPS{$op_type}{$co}; die("Undefined operation $co.\n") unless $op; $r &= $op->($v, $cv);

        It would be even better if you could alter the code which sets up %types, so that instead of true and false values, it could store the strings we need: 'num' or 'str'.

        --
        TTTATCGGTCGTTATATAGATGTTTGCA

Re: What does 'last OP;' do?
by Solo (Deacon) on Jan 21, 2005 at 21:12 UTC
    What is the OP: ?

    It's a block label used here as part of a switch. Check out perlsyn.

    --Solo

    --
    You said you wanted to be around when I made a mistake; well, this could be it, sweetheart.
Re: What does 'last OP;' do?
by ww (Archbishop) on Jan 21, 2005 at 21:15 UTC
    Indeed, each is a label, providing a target for the various "if"s which follow each.

    Think you'll find help in
    perldoc -f last

Re: What does 'last OP;' do?
by atcroft (Abbot) on Jan 21, 2005 at 21:27 UTC

    $v is set with the content of the 0th element of the array that is the content of hash %pairs when keyed by the value $ca. If the content of the %types hash when keyed by the value $ca is true (non-zero), the operations assume that $v and $cv are numeric (otherwise assuming them to be strings). $v is given an empty value if it has not been previously defined, and $r is set to the result of a bitwise AND operation of itself and the result of the appropriate comparison, as selected by the value in $co.

    HTH.