in reply to pack() returns an unusable string

G'day Rob,

I'm not sure if this helps, but it seems to reproduce what you're describing on a different platform: Cygwin 3.2.0 on Win10. I kept most of your posted code as is; I added some info up front; and, I looped through all of the templates on both 5.32 and 5.34.

$ cat pm_11133064_pack_test.pl use warnings; print "OS: $^O; Perl: $^V;\n", `perl -V:usequadmath`, `perl -V:nvtype`, "\n"; my @templates = qw{d d< d> D D< D>}; for $template (@templates) { print "TEMPLATE: $template\n"; $nv = 2.4; $p = pack $template, $nv; $s = "'$p'"; system $^X, '-wle', "print unpack('H*', $s);"; }
$ perl pm_11133064_pack_test.pl OS: cygwin; Perl: v5.32.0; usequadmath='undef'; nvtype='double'; TEMPLATE: d 3333333333330340 TEMPLATE: d< 3333333333330340 TEMPLATE: d> 4003333333333333 TEMPLATE: D Invalid type 'D' in pack at pm_11133064_pack_test.pl line 11.
$ perl pm_11133064_pack_test.pl OS: cygwin; Perl: v5.34.0; usequadmath='undef'; nvtype='double'; TEMPLATE: d 3333333333330340 TEMPLATE: d< 3333333333330340 TEMPLATE: d> 4003333333333333 TEMPLATE: D Can't find string terminator "'" anywhere before EOF at -e line 1. TEMPLATE: D< Can't find string terminator "'" anywhere before EOF at -e line 1. TEMPLATE: D> Can't find string terminator "'" anywhere before EOF at -e line 1.

— Ken

Replies are listed 'Best First'.
Re^2: pack() returns an unusable string
by syphilis (Archbishop) on May 27, 2021 at 13:50 UTC
    I'm not sure if this helps ...

    Heh ... it helps ... but only in that it reaffirms what I already knew ;-)

    I'll elaborate a little on how this all came about.
    As I mentioned in the opening post, with perl-5.34.0, pack's 'D' templates are allowed on all builds irrespective of whether $Config{nvtype} is 'double' or 'long double' or '__float128'.
    In earlier perl versions the 'D' templates were supported only if $Config{nvtype} was 'long double'.

    With perl-5.34.0 and nvtype of 'long double' we get:
    C:\>perl -wle "print unpack 'H*', pack 'D', 2.4;" 9a999999999999990040000000000000
    whereas with perl-5.34.0 and nvtype of double, the same command yields a slightly different result:
    C:\>perl -wle "print unpack 'H*', pack 'D', 2.4;" 00989999999999990040000000000000
    That's pretty much as I expected because the string being unpacked in the first one-liner is different to the string being unpacked in the second one-liner.
    But then I wanted to see what the result would be if the string created on the long double build (in the first one-liner) was fed to the 'double' build (in the second one-liner).
    Would the result be 9a999999999999990040000000000000 or 00989999999999990040000000000000 ?
    (I was quite sure it would be the former, but I knew that if I didn't check then I'd get it wrong.)

    So I thought I'd do something cute:
    I decided that, on my 'long double' build, I would run the following script:
    use warnings; $template = 'D<'; $nv = 2.4; $p = pack $template, $nv; $s = "'$p'"; # Now pass $p to the 'double' build of perl. $double_perl = "C:/perl-5.34.0/bin/MSWin32-x64-multi-thread/perl.exe"; system $double_perl, '-wle', "print unpack('H*', $s);";
    But, as already demonstrated, that doesn't DWIM.

    In the end, I took the clunky approach of running 2 scripts.
    Firstly, on the 'long double' build of perl-5.34.0 I ran the following script that would print the string returned by pack() to a file:
    use warnings; $p = pack("D", 2.4); open WR, '>', 'packstr.txt' or die "Opening: $!"; binmode(WR); print WR $p; close WR or die "Closing: $!";
    Then, on the 'double' build of perl-5.34.0, I ran a script that passed the string that was saved in packstr.txt to unpack():
    use warnings; open RD, '<', 'packstr.txt' or die "Opening: $!"; binmode(RD); $p = <RD>; close RD or die "Closing: $!"; print unpack("H*", $p);
    That script output 9a999999999999990040000000000000.
    (Hmph ... as if it was ever going to do anything else ...)

    It just would have been so much cleaner and simpler if I could have got the first approach to work.

    Cheers,
    Rob