This isn't the same thing as the base node. There were no breaks inside the switch so it would keep falling through from the matched value to the bottom. Yours would be right if there were a break after each statement.
---
print map { my ($m)=1<<hex($_)&11?' ':'';
$m.=substr('AHJPacehklnorstu',hex($_),1) }
split //,'2fde0abe76c36c914586c';
| [reply] [d/l] |
Point taken. I guess there is a reason I stick with Perl: my C always did suck.
| [reply] |
Not just your C; C sucks in general. As a case in
point, the C case statement is next-to-worthless,
because fallthrough is not usually what you want.
There are cases for it, but they're the exception
rather than the rule. As a result, you end up
needing to insert break statements at nearly every
case, at which point you have barely less typing to
do than with a nested if structure. Perl's elsif
is actually an improvement on this.
The case statement in Inform (and even SELECT CASE
in BASIC) is much more useful. If Perl
ever gets a case, I hope the breaks are implied;
otherwise I'll end up never using it.
Most of the cases where you want the
fallthrough, it's because what you want is actually
not a case statement, but some other structure.
This is a perfect example. What it's doing is
not really unique to each case; there are some
minor variations, but what you really want is
a loop.
Others have done efficient things (and I particularly
like the pack solution), but I'll add my own
translation, on the grounds that it is straightforward
and legible...
{ my @shiftby = (0, 8, 16, 24, 0, 8, 16, 24, 8, 16, 24);
my $l;
foreach $l (reverse 1 .. $len) {
if ($l>8) { $c += $k[$l-1]<<$shiftby[$l]; }
elsif ($l>4) { $b += $k[$l-1]<<$shiftby[$l]; }
else { $a += $k[$l-1]<<$shiftby[$l]; }
}
}
I've reduced the number of +=
operations to three,
and it is easy to see where the similarities and
the differences are. The if/elsif/else makes it
stand out when you are incrementing a different
variable. (When I first looked at the thing, I
thought the same variable was being incremented
ten times.) Even better, it is clear how @k is
being used; before, you had to look at each line
and compare the index to @k with the case number,
if you wanted to know if there were any deviations
from the pattern; here it's clear there are none;
$l-1 is always $l-1.
@shiftby could probably also be replaced with an
arithmetic expression, but I'm not sure that would
improve clarity.
--jonadab | [reply] [d/l] [select] |
| [reply] |