Front page | perl.perl5.porters |
Postings from May 2015
[perl #125266] Unexpected interaction between binary multiplication operator and Test::More::cmp_ok()
Thread Previous
|
Thread Next
From:
James E Keenan
Date:
May 28, 2015 14:22
Subject:
[perl #125266] Unexpected interaction between binary multiplication operator and Test::More::cmp_ok()
Message ID:
rt-4.0.18-12689-1432822922-48.125266-75-0@perl.org
# New Ticket Created by James E Keenan
# Please include the string: [perl #125266]
# in the subject line of all future correspondence about this issue.
# <URL: https://rt.perl.org/Ticket/Display.html?id=125266 >
Today I was bitten by an unexpected interaction between Perl's binary multiplication operator (*) and Test::More::cmp_ok(). I got expected results only on very old versions of Perl and Test::More. Though I was able to compensate for this problem on newer versions of Perl and Test::More, the fact that I got unexpected results suggests either the presence of a bug or the need for some cautionary documentation somewhere.
The situation: I needed to test whether I was getting expected values of prices stored in US dollars (USD) but converted to Japanese yen (JPY). For testing purposes, I assumed that the JPY/USD exchange rate was 8:1.
Consider the program attached, 'cmp_ok.pl', which illustrates four different usages of Test::More::cmp_ok(). Cet. par., I would expect all four to PASS and, when run with perl-5.6.2 and the version of Test::More that came with that perl, 0.47, the do.
#####
$ perlbrew switch perl-5.6.2
$ perl cmp_ok.pl
ok 1 - Perl version: 5.006002
ok 2 - Test::More version: 0.47
ok 3 - Use Test::More::cmp_ok() to compare two floats
ok 4 - Both floats explicitly assigned; compare with '=='
ok 5 - Both floats explicitly assigned; compare with 'eq'
ok 6 - One float explicitly assigned, one calculated via '*'; compare with '=='
ok 7 - One floatexplicitly assigned, one calculated via '*' then sprintf-ed; compare with '=='
1..7
#####
However, when I switch to perl-5.8.9 and the version of Test::More that came with that perl, 0.80, the third test FAILs. In the third test, I calculate the expected JPY price by multiplying the USD price by the JPY/USD exchange rate -- multiplication of two floats -- and assign the result to $calculated_jpy, which I then use in the next instance of 'cmp_ok'. The output of 'cmp_ok' suggests that the two values are not mathematically equal even though the 'got' and 'expected' outputs are identical!
$ perlbrew switch perl-5.8.9
$ perl cmp_ok.pl
ok 1 - Perl version: 5.008009
ok 2 - Test::More version: 0.8
ok 3 - Use Test::More::cmp_ok() to compare two floats
ok 4 - Both floats explicitly assigned; compare with '=='
ok 5 - Both floats explicitly assigned; compare with 'eq'
not ok 6 - One float explicitly assigned, one calculated via '*'; compare with '=='
# Failed test 'One float explicitly assigned, one calculated via '*'; compare with '==''
# at cmp_ok.pl line 20.
# got: 1.68
# expected: 1.68
ok 7 - One floatexplicitly assigned, one calculated via '*' then sprintf-ed; compare with '=='
1..7
# Looks like you failed 1 test of 7.
#####
Testing on more recent perl/Test::More combinations, I get the same results as I did on 5.8.9/0.80. Example:
#####
$ perlbrew switch perl-5.20.1
$ perl cmp_ok.pl
ok 1 - Perl version: 5.020001
ok 2 - Test::More version: 1.001002
ok 3 - Use Test::More::cmp_ok() to compare two floats
ok 4 - Both floats explicitly assigned; compare with '=='
ok 5 - Both floats explicitly assigned; compare with 'eq'
not ok 6 - One float explicitly assigned, one calculated via '*'; compare with '=='
# Failed test 'One float explicitly assigned, one calculated via '*'; compare with '==''
# at cmp_ok.pl line 20.
# got: 1.68
# expected: 1.68
ok 7 - One floatexplicitly assigned, one calculated via '*' then sprintf-ed; compare with '=='
1..7
# Looks like you failed 1 test of 7.
#####
Note that when I sprintf-ed the product of the multiplication and used the result in 'cmp_ok', I got the expected PASS (fourth instance in each perl version).
I haven't yet had time to figure out whether the change in behavior between 5.6.2/0.47 and 5.8.9/0.80 occurred in perl or in Test::More. But I suspect that this surprising behavior needs to be documented somewhere.
Recommendations?
Thank you very much.
Jim Keenan
James E Keenan (jkeenan@cpan.org)
Thread Previous
|
Thread Next