Hi Monks,
I was kind of puzzled when I found out the following. It is
probably perfectly logical, however ... it puzzled me.
I have the following piece of code (thanks ChOas) which sorts
version-numbers (1.0.a, 1.0.10, 5.5.001, et cetera).
Now I decided that I also needed a similar function that I could
use to compare version-numbers. (Returning -1 when the left
parameter is smaller than the right, returning a 0 when they're
equal and returning a 1 when the left is greater than the right.
This is exactly the same function, not taking the fact that I need
to pass two parameters to it, into account. So I decided to try and
integrate them into one subroutine ...
#!/usr/bin/perl -w
use strict;
sub byVersion;
my ($v1,$v2)=("1.1.1.1","1.1.1.2");
print "$v1 is equal to $v2\n" if (byVersion($v1,$v2)== 0);
print "$v1 is greater than $v2\n" if (byVersion($v1,$v2)== 1);
print "$v1 is less than $v2\n" if (byVersion($v1,$v2)==-1);
sub byVersion
{
my @First=split /\./,$a||shift;
my @Second=split /\./,$b||shift;
foreach(0..(($#First>$#Second)?$#Second:$#First))
{
next if ($First[$_] eq $Second[$_]);
return (($First[$_]=~/^\d+$/o)&&($Second[$_]=~/^\d+$/o))?($First[$_]
+<=>$Second[$_]):($First[$_] cmp $Second[$_]);
}
return ($#First<=>$#Second);
}
Doing this results in the following error:
srmpilot@IBP-test$ ./sort.s
Name "main::a" used only once: possible typo at ./sort.s line 20.
Name "main::b" used only once: possible typo at ./sort.s line 21.
1.1.1.1 is less than 1.1.1.2
Which ofcourse is very understandable. I do not use the
$a en
$b
variables (normally passed on by
sort in this example ... I would, however,
in an example in which I needed to actually sort a bunch of versions (see below).
#!/usr/bin/perl -w
use strict;
sub byVersion;
my ($v1,$v2)=("1.1.1.1","1.1.1.2");
#-----------------------------
my @row=(1,2,3,4);
my @nrow=sort byVersion @row;
print "@nrow\n";
#-----------------------------
print "$v1 is equal to $v2\n" if (byVersion($v1,$v2)== 0);
print "$v1 is greater than $v2\n" if (byVersion($v1,$v2)== 1);
print "$v1 is less than $v2\n" if (byVersion($v1,$v2)==-1);
sub byVersion
{
my @First=split /\./,$a||shift;
my @Second=split /\./,$b||shift;
foreach(0..(($#First>$#Second)?$#Second:$#First))
{
next if ($First[$_] eq $Second[$_]);
return (($First[$_]=~/^\d+$/o)&&($Second[$_]=~/^\d+$/o))?($First[$_]
+<=>$Second[$_]):($First[$_] cmp $Second[$_]);
}
return ($#First<=>$#Second);
}
Running this results in:
srmpilot@IBP-test$ ./sort.s
1 2 3 4
1.1.1.1 is less than 1.1.1.2
I DO understand the fact that he sorted the row correctly.
Because he used the
$a and
$b variables ... so, no
error-message appeared. However, I do NOT understand the fact that
the
Name "main::a" used only once: possible typo error
didn't occur the second time, while comparing the
$v1 and
$v2
variables. Because the second time it goes into the
byVersion sub
the
$a and
$b aren't used (as in the above example)
So a)... what happened to the error message ? and b) Is there an easier
way to use
byVersion for the two above mentioned (2) purposes ?
I thought of doing something like:
my ($val1,$val2)=("1.1.2","1.1.3");
print "Greater than\n" if ((sort byVersion ($val1,$val2))[-1] eq $val1
+);
Which works o.k. for this example, however it would give problems
for
Smaller than and especially for
equals.
Suggestions anyone ? Your help is very much appreciated !
Thanks and Bye, Leon
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.