Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does loading Test::More eliminate my bug?

I'm trying to write a test for this bug. I've already found a solution to the bug; what I can't understand is why my tests didn't catch the bug before release.

The problem boils down to this command line printing Ver: 0 when it's supposed to print Ver: 1.00:

perl -Mversion -e 'printf "Ver: %s\n", ("v1.00" =~ /v(.+)/ ? version->parse($1) : "no");'

However, if you insert -MTest::More before -Mversion, then it prints Ver: 1.00.

So my question is why does loading Test::More change the behavior of my code? (For bonus points, why does using "$1" instead of $1 eliminate the bug?)

I'm using Perl 5.14.2, Test::More 0.98, and version 0.88.

like image 312
cjm Avatar asked Nov 09 '12 18:11

cjm


2 Answers

It's a bug in version. $1 is magical var, and version fails to process magic before checking if the arg is defined. It thinks $1 is undefined if no one ever read from $1. If someone has read from $1 (e.g. Test::More), then it appears defined to version.

$ perl -Mversion -E'
    "v1.00" =~ /v(.+)/ or die;
    $x=$1 if $ARGV[0];
    say version->parse($1);
' 0
0

$ perl -Mversion -E'
    "v1.00" =~ /v(.+)/ or die;
    $x=$1 if $ARGV[0];
    say version->parse($1);
' 1
1.00

I have filed a bug report: Perl RT#115660

like image 165
ikegami Avatar answered Sep 19 '22 18:09

ikegami


perl -Mversion -E 'sub TIESCALAR { bless {} }; sub FETCH { die "HERE" }; tie $foo, __PACKAGE__; say version->new($foo)'

version is buggy, it doesn't call get magic properly, thus never populating $1. If it works when loading Test::More first, that's only because there's still an old value in $1

like image 30
Leon Timmermans Avatar answered Sep 17 '22 18:09

Leon Timmermans