Sometimes, all it takes is a simple change to make your Perl code run on Windows

Inspired by brian’s Perl on Windows project, I decided to build perl 5.18.2 on an old laptop with Windows Vista 32-bit and MSVC++ Express version 10. Downloaded the source tarball, extracted it, edited win32/Makefile, and a simple nmake got the job done. I had a couple of issues because I had forgotten to ensure that there were no Cygwin related directories in the path, but after I fixed that tests went wonderfully.

I then downloaded the tarball for cpanm, perl Makefile.PL, nmake, nmake test, and nmake install and I had cpanm.

Then I pushed it a little by entering:

cpanm Dancer2

on the command line. Things worked well, until the installation stopped due to a failure to install Test::SharedFork:

t\06_fail_lineno.t ....... 1/2
#   Failed test at t\06_fail_lineno.t line 20.
#                   'not ok 1
#
# #   Failed test at t\06_fail_lineno.t line 15.
# '
#     doesn't match '(?^:t/06_fail_lineno.t line \d+\.)'
# Looks like you failed 1 test of 2.

I stared at that code, not seeing what was wrong. Then, I went to bed. When I woke up this morning, I kicked off some long running jobs on a remote server, and then looked at that laptop again. All of a sudden, it was obvious:

like($out, qr{t/06_fail_lineno.t line \d+\.});

Yup, the output used \ whereas the test used /.

Of course, changing the pattern to qr{t(?:/|\\)06_fail_lineno.t line \d+\.} “fixes” the problem.

But, that is not right, because it would allow a t\06_fail_lineto.t to pass on a Unixy system.

File::Spec has been in the core for a long time now. Using catfile to create the path does the right thing:

use File::Spec::Functions qw/catfile/;
...
{
    my $path = catfile(qw(t 06_fail_lineno.t));
    like($out, qr{\Q$path\E line \d+\.});
}