Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: pack() returns an unusable string

by tybalt89 (Monsignor)
on May 26, 2021 at 18:37 UTC ( [id://11133085]=note: print w/replies, xml ) Need Help??


in reply to pack() returns an unusable string

From your warning message, I would guess that your packed string '$p' has either a single quote "'" in it or an escape or $ or @ at the end that eats the closing single quote. Try looking at a dumped wersion of $p.

Replies are listed 'Best First'.
Re^2: pack() returns an unusable string
by syphilis (Archbishop) on May 27, 2021 at 00:32 UTC
    I would guess that your packed string '$p' has either a single quote "'" in it or an escape or $ or @ at the end that eats the closing single quote

    I should add that there's nothing special about the given NV value of 2.4.
    The behaviour I'm seeing is happening for all NV values that I've tested.

    To get a dump of $s:
    # test.pl use warnings; use Devel::Peek; $template = 'D<'; $nv = 2.4; $p = pack $template, $nv; $s = "'$p'"; Dump $s; system $^X, '-wle', "print unpack('H*', $s);";
    That outputs the following (which does, at least, contain an "@"):
    C:\_32\pscrpt>perl test.pl SV = PV(0x4bcf98) at 0x571248 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x4b7e88 "'\232\231\231\231\231\231\231\231\0@\0\0\0\0\0\0'"\0 CUR = 18 LEN = 20 Can't find string terminator "'" anywhere before EOF at -e line 1.
    But if I change the value of $nv to 2.4e100, I get:
    C:\_32\pscrpt>perl test.pl SV = PV(0x3ecf98) at 0x383348 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x3e7e88 "'\vL\177v\257zb\206\264>\0\0\0\0\0\0'"\0 CUR = 18 LEN = 20 Can't find string terminator "'" anywhere before EOF at -e line 1.
    Interestingly, changing the value to 3.1e-100 results in a different warning:
    C:\_32\pscrpt>perl test.pl SV = PV(0x26cf98) at 0x5311f8 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x267e88 "'9\302\271\243\"\211\224\255\264>\0\0\0\0\0\0'"\0 CUR = 18 LEN = 20 Use of uninitialized value $_ in print at -e line 1.
    Perhaps something to do with the internal double quote.

    For a value of 13.16e-100, I get:
    C:\_32\pscrpt>perl test.pl SV = PV(0x38cf98) at 0x4c51b8 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x387e88 "'\245^,\356\266\0208\270\266>\0\0\0\0\0\0'"\0 CUR = 18 LEN = 20 Can't find string terminator "'" anywhere before EOF at -e line 1.
    Is there some way to pass the string returned by pack() to that system command ?
    I assume that it ought to be possible, and that I'm just doing something dumb.

    Cheers,
    Rob

      And here's a version with Data::Dumper and some config vars that also works.

      #!/usr/bin/perl -l use strict; # https://perlmonks.org/?node_id=11133064 use warnings; my $template = 'd<'; my $nv = 2.4; $nv = 4135; # NOTE errors for this number my $p = pack $template, $nv; use Data::Dumper; $Data::Dumper::Terse = $Data::Dumper::Useqq = 1; my $s = Dumper $p; print ">$s<\n"; system $^X, '-wle', "use strict; print unpack('H*', $s);";

      Outputs:

      >"\0\0\0\0\0'\260\@" < 000000000027b040

      note that it adds a newline, but perl doesn't care.

        And here's a version with Data::Dumper and some config vars that also works

        Neither this nor the rendition using Data::Dump works for me on Windows:
        C:\_32\pscrpt>type test3.pl use strict; # https://perlmonks.org/?node_id=11133064 use warnings; my $template = 'd<'; my $nv = 2.4; $nv = 4135; # NOTE errors for this number my $p = pack $template, $nv; use Data::Dumper; $Data::Dumper::Terse = $Data::Dumper::Useqq = 1; my $s = Dumper $p; print ">$s<\n"; system $^X, '-wle', "use strict; print unpack('H*', $s);"; C:\_32\pscrpt>perl test3.pl >"\0\0\0\0\0'\260\@" < syntax error at -e line 1, at EOF Execution of -e aborted due to compilation errors. C:\_32\pscrpt>
        I guess it's something to do with Windows command line quoting rules.
        Mind you, having it work on Windows specifically is not important.
        Now that I have a working example, I can while away some time porting your fix to Windows when I have nothing better to do.

        Thanks tybalt89 !!

        Cheers,
        Rob

        Thanks

      This seems to work :)

      #!/usr/bin/perl -l use strict; # https://perlmonks.org/?node_id=11133064 use warnings; my $template = 'd<'; my $nv = 2.4; $nv = 4135; # NOTE errors for this number my $p = pack $template, $nv; use Data::Dump qw(pp); my $s = pp $p; print ">$s<\n"; system $^X, '-wle', "use strict; print unpack('H*', $s);";

      Outputs:

      >"\0\0\0\0\0'\xB0\@"< 000000000027b040
Re^2: pack() returns an unusable string
by GrandFather (Saint) on May 26, 2021 at 22:30 UTC

    Guessing is sometimes fine, but the OP gave an entire and complete test script which you can examine and even run. If I make a small modification to the test script given we can test the theory:

    # test.pl use warnings; $template = 'd<'; $nv = 2.4; $p = pack $template, $nv; $s = "'$p'"; print ">$s<\n"; system $^X, '-wle', "print unpack('H*', $s);";

    prints:

    >'333333@'< 3333333333330340

    running a 64 bit build of 5.32. Note that there is an ETX character between the final 3 and the @ character, which, when you think about it, is the string that the unpack is showing us so for the success case there is a trailing @ and it isn't swallowing the trailing '.

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond

      OP said error only happens on D<, not d<, which doesn't run on my machine.

      However, here is a number for which the error occurs on 5.32 with d<

      #!/usr/bin/perl -l use strict; use warnings; my $template = 'd<'; my $nv = 2.4; $nv = 4135; # NOTE errors for this number my $p = pack $template, $nv; my $s = "'$p'"; print ">$s<\n"; system $^X, '-wle', "print unpack('H*', $s);";

      Outputs:

      >''°@'< Can't find string terminator "'" anywhere before EOF at -e line 1.

      which shows that my guess that the pack produces a single quote character is plausible.

        In blead, it runs with D< and fails with
        Can't find string terminator "'" anywhere before EOF at -e line 1.

        However, when I tried to output

        say join ', ', map ord, split //, $p;
        I got
        0, 152, 153, 153, 153, 153, 153, 153, 0, 64, 0, 0, 0, 0, 0, 0

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11133085]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-19 22:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found