I have inherited some code from a guy whose favorite past time was to shorten every line to its absolute minimum (and sometimes only to make it look cool). His code is hard to understand but I managed to understand (and rewrite) most of it.
Now I have stumbled on a piece of code which, no matter how hard I try, I cannot understand.
my @heads = grep {s/\.txt$//} OSA::Fast::IO::Ls->ls($SysKey,'fo','osr/tiparlo',qr{^\d+\.txt$}) || ();
my @selected_heads = ();
for my $i (0..1) {
$selected_heads[$i] = int rand scalar @heads;
for my $j (0..@heads-1) {
last if (!grep $j eq $_, @selected_heads[0..$i-1]);
$selected_heads[$i] = ($selected_heads[$i] + 1) % @heads; #WTF?
}
my $head_nr = sprintf "%04d", $i;
OSA::Fast::IO::Cp->cp($SysKey,'',"osr/tiparlo/$heads[$selected_heads[$i]].txt","$recdir/heads/$head_nr.txt");
OSA::Fast::IO::Cp->cp($SysKey,'',"osr/tiparlo/$heads[$selected_heads[$i]].cache","$recdir/heads/$head_nr.cache");
}
From what I can understand, this is supposed to be some kind of randomizer, but I never saw a more complex way to achieve randomness. Or are my assumptions wrong? At least, that’s what this code is supposed to do. Select 2 random files and copy them.
=== NOTES ===
The OSA Framework is a Framework of our own. They are named after their UNIX counterparts and do some basic testing so that the application does not need to bother with that.
This looks like some C code with Perl syntax. Sometimes knowing the language the person is thinking in helps you figure out what’s going on. In this case, the person’s brain is infected with the inner workings of memory management, pointer arithmetic, and other low level concerns, so he wants to minutely control everything:
This is a lot of work because the original programmer either doesn’t understand hashes or doesn’t like them.
If you still hate hashes and have Perl 5.10 or later, you can use smart-matching to check if a value is in an array:
However, you have a special constraint on this problem. Since you know there are only two elements, you just have to check if the element you want to add is the prior element. In the first case it won’t be undef, so the first addition always works. In the second case, it just can’t be the last element in the array:
Huh. I can’t remember the last time I used
untilwhen it actually fit the problem. 🙂Note that all of these solutions have the problem that they can cause an infinite loop if the number of original files is less than 2. I’d add a guard condition higher up so the no and single file cases through an error and perhaps the two file case doesn’t bother to order them.
Another way you might do this is to shuffle (say, with List::Util) the entire list of original files and just take off the first two files: