Gabriella said:
I figure that this code try to compare 2 ligns and sort them in
increasing number. 1.2.3 is greater 1.2.2. What I don't see why the
person who codes this introduce the $imgA, $imgB What is he trying to
achieve ?
sub sortRule {
my ($wordA, $wordB, @numA, @numB, $lgA, $lgB, $min, $imgA, $imgB);
$wordA = $a;
$wordB = $b;
#print "\nwordA=$wordA\n";
#print "wordB=$wordB\n";
$wordA =~ s/^([0-9.]+).*$/$1/;
$wordB =~ s/^([0-9.]+).*$/$1/;
#printc "a=$wordA b=$wordB", 'blue';
@numA = split(/\./, $wordA);
@numB = split(/\./, $wordB);
$lgA = $#numA;
$lgB = $#numB;
#printc "lgA=$lgA, lgB=$lgB";
if ($lgA > $lgB) { $min = $lgB }
else { $min = $lgA }
my $fin = 0;
for (my $i=0; ($i<=$min && !$fin); $i++) {
if ($numA[$i] > $numB[$i]) {
$imgA = 2;
$imgB = 1;
$fin = 1;
}
elsif ($numA[$i] < $numB[$i]) {
$imgA = 1;
$imgB = 2;
$fin = 1;
}
}
if (!$fin) {
if ($lgA > $lgB) {
$imgA = 2;
$imgB = 1;
}
else {
$imgA = 1;
$imgB = 2;
}
}
#printc "imgA=$imgA, imgB=$imgB", 'green';
return ($imgA <=> $imgB);
}
Dear Gabriella,
Hmm... the code is difficult to read. It bothers me when people
figure out a process to achieve what they want, and then don't even
bother to explain it, as if their way is the only way that could ever
be thought of or they think their method is so clear that it needs no
explanation. In other words, if you think up a solution, it's a good
idea to explain along the way what you are doing, in case somebody
after you ever tries to figure out what you are doing. (I definitely
think that you should write the simplest, clearest code, but even then
it's not always clear what the code is trying to do, which is why I
think good code should have in-code documentation (in the form of
comments) explaining what is being done.)
I looked at the code, and it appears that $imgA and $imgB (I don't
know what "img" is supposed to stand for) are temporary placeholders
that keep track of which value ($a or $b) is greater. When they are
set, one of them receives a value of 1 and the other a value of 2. The
one that got the value of 2 represents the greater value. For example,
if $imgA gets the value of 2, it means that $a was determined to be the
greater value.
No comments were included to specify this. It would have been nice
if the original writer of the code mentioned this. As for me, I think
it would have been clearer if, instead of setting $imgA, $imgB, and
$fin, that the function would end immediately returning 1 (if $a was
greater) or -1 (if $b was greater). At the end of the function, if no
value was found to be greater, then 0 would be returned.
To illustrate my point, I have included my own small program, which
is hopefully clearer to you (and should do the same thing):
============= START OF CODE ================
#!/usr/bin/perl
use strict;
use warnings;
sub specialSort
{
# Note: 1.2.3 is greater than 1.2.2
# Split out all numbers into arrays @a and @b:
my @a = split(/\./, $a);
my @b = split(/\./, $b);
# Compare the numbers in each array.
# As soon as the number differ, return
# the proper value (-1 if $a is greater;
# 1 if $b is greater):
while (@a and @b)
{
my $aNum = shift @a;
my $bNum = shift @b;
return -1 if $aNum < $bNum; # b is greater
return 1 if $aNum > $bNum; # a is greater
}
# All the values so far were identical.
# If one array still contains values, then
# it's value is greater:
return -1 if @b; # b is greater
return 1 if @a; # a is greater
return 0; # both numbers the same
}
### Main code: ###
# Get the numbers:
my @listOfNums = <DATA>;
chomp(@listOfNums); # remove the newlines
# Do the sort:
my @sortedNums = sort specialSort @listOfNums;
# Print out the sorted values:
print "$_\n" foreach @sortedNums;
__DATA__
7
5.2
5.7
5.9
8.56.4.3
5.0
5.5.5
1.788.34.3
5.5.4
5.2.6
5.2.6.7
============= END OF CODE ================
There is only one problem that I see with my code, and that is that
it treats the value 5.0 to be greater than 5 . This might be what you
want (or it might not), so you will have to modify it (to check for
something like m/(\.0)*$/ ) if you need 5 to equal 5.0 .
I hope this helps, Gabriella.
-- Jean-Luc