I have been trying to make a relatively large Perl program that has been working perfectly fine on CentOS for many years to work on Ubuntu and this has become a huge nightmare. CentOS uses Perl built for x86_64-linux-thread-multi and Ubuntu uses the x86_64-linux-gnu-thread-multi build. AFAIK, the interpreter behavior should be the same in both environments when the program invokes the same previous version v5.10.1
. However I have been getting very different behavior, including warnings about given
/when
and smartmatch
being experimental and, most importantly, a set of nasty bugs that are hard to trace and resolve. A particular problem occurs when a given
statement shown below (form 1) matches and calls a function. Then suddenly the value of the switch variable (called $ailtype
) that is never otherwise touched gets erased from memory! If I simply call that function nothing obnoxious happens. So, I replaced the given
/when
usage with a for
statement (form 2) and my question is why does the the problem still occur?! The only form that truly avoids the problem is a simple chain of if
/elsif
s (form 3) and this clearly shows that the problem is with forms 1 and 2 and the perl interpreter being inconsistent and bug-ridden: it does not even produce an "experimental" warning for form 2.
Here is form 1 (original):
print "ailtype is $ailtype \n"; # prints "ailtype is 8"
given ($ailtype) {
when (4) { &parse_mascot}
when (5) { &parse_sequest}
when (8) { &parse_spectrast($ms2_results, $rttemp)}
when (9) { &parse_cnstab($ms2_results, $rttemp)}
default { STDOUT->autoflush(1) and die "ailtype=|$ailtype| unknown.\n"; }
}
print "ailtype is $ailtype \n"; # prints "ailtype is ". $ailtype got destroyed!
The print
s are for debug. I can put them inside the when
block and confirm that $ailtype
gets destroyed after the &parse_spectrast
function call. However, the function does not read or touch $ailtype
at all! (Interestingly, if I go inside the function and print the value of $ailtype
to find exactly where it gets messed up, I see that it occurs within a while
loop parsing the lines of an input file. Printing $ailtype
somehow returns the lines of that file!)
The program consists of several large perl files with many given
/when
statements and re-writing all of them by hand would be tedious. I have to make sure that the alternative form works. So I tried form 2 (suggested here):
print "ailtype is $ailtype \n"; # prints "ailtype is 8"
for ($ailtype) {
/4/ and do { &parse_mascot; last};
/5/ and do { &parse_sequest; last};
/8/ and do { &parse_spectrast($ms2_results, $rttemp); last};
/9/ and do { &parse_cnstab($ms2_results, $rttemp); last};
do { STDOUT->autoflush(1) and die "ailtype=|$ailtype| unknown.\n"; }
}
print "ailtype is $ailtype \n"; # prints "ailtype is ". $ailtype still gets destroyed!
The problem still occurs in this form, and I really don't understand why?! The interpreter no longer warns about experimental given
/when
here (they're still used elsewhere in the code though. I ensured they didn't occur before the problematic block and that didn't help).
Surprising or not, a chain of if
/elsif
s (form 3) works fine:
print "ailtype is $ailtype \n"; # prints "ailtype is 8"
if (4 == $ailtype) {
&parse_mascot;
}
elsif (5 == $ailtype) {
&parse_sequest;
}
elsif (8 == $ailtype) {
&parse_spectrast($ms2_results, $rttemp);
}
elsif (9 == $ailtype) {
&parse_cnstab($ms2_results, $rttemp);
}
else {
STDOUT->autoflush(1) and die "ailtype=|$ailtype| unknown.\n";
}
print "ailtype is $ailtype \n"; # prints "ailtype is 8". It was never changed.
But I thought the powers of Perl were there to save us from having to code all of this. I would be willing to do so if I was sure I had an otherwise reliable interpreter. Changing the version to v5.16.3 (the latest installed on both platforms) only produces new errors regarding declarations, "bareword STDOUT not allowed", etc. Having fought with this bug alone for 10 hours, I am seriously in doubt.
$ailtype
at all. Not even mention it once. The fact that simply calling the point-of-problem function or usingif
avoids the problem should make it clear that it doesn't matter what the functions do. – Candracandyuse v5.10.1
will make it use this version of Perl - it doesn't. It only makes sure that you are running at least 5.10.1 and it will switch on some features introduced with 5.10.1. – Catercornergiven
-when
and smartmatch (in particular!) have serious problems and that they will be changed, perhaps beyond recoginition (or worse)? Tedious or not, just replace those code sections, and be careful to use the simplest and clearest code possible (part of the problem with those overloaded features, that they quietly pull in all kinds of assumptions). Sorry. It happens. – Lindsylindygiven
-when
or smartmatch, or does it implicitly? – Candracandygiven
-when
or smartmatch" -- true, that's where another problem got introduced (as choroba shows) -- essentially because of trying to re-implement them and stick to their logic. (Note yet another problem: that/4/
matches41
as well as4
or14
. Maybe not an issue but did you think of that? Got to be really careful when rewriting code.) – Lindsylindy/4/
matching other numbers! Didn't think of that. Thank you very much!! You are exactly right, this is important software that our whole research lab and collaborators rely on and needs to be stable and cross-platform. – Candracandy