http://www.perlmonks.org?node_id=317125

bl0rf has asked for the wisdom of the Perl Monks concerning the following question:

After reading the pack/unpack tutorial by pfaut I felt brave and decided to do some things with the scariest function in Perl. I saw something very weird that I hope you might explain to me.

$number = 1145258561; print pack( "l", $number ); # prints: ABCD
The number above is the result of a concatenation of the letters ABCD ( I'll put the whole thing in the code snippets section later ). What I don't understand is why Perl convert the number into four characters instead of into a "long" number

I'm completely puzzled, and Perl even converts the number into the correct letters ( okay, I converted them to binary, concatenated and converted to a long again before doing the above ). Could somebody explain this madness to me, as my work with pack/unpack is purely hit-and-miss :-(

Thanks for your help.

Replies are listed 'Best First'.
Re: pack peculiarity
by !1 (Hermit) on Dec 26, 2003 at 21:50 UTC

    What were you expecting?

    packing returns a a string that is used by perl for converting between different encodings. The value you are seeing (ABCD) is the value that perl is using. Observe:

    #!/usr/bin/perl -wl use strict; my $z = pack "l",1145258561; print my $h = unpack "h*",$z; print my $H = unpack "H*",$z; print my $A = unpack "A*",$z; print my $B = unpack "B*",$z; print my $b = unpack "b*",$z; print my $f = unpack "f*",$z; print my $l = unpack "l*",$z; print my $L = unpack "L*",$z; print pack "h*",$h; print pack "H*",$H; print pack "A*",$A; print pack "B*",$B; print pack "b*",$b; print pack "f*",$f; print pack "l*",$l; print pack "L*",$L; __END__ 14243444 41424344 ABCD 01000001010000100100001101000100 10000010010000101100001000100010 781.035217285156 1145258561 1145258561 ABCD ABCD ABCD ABCD ABCD ABCD ABCD ABCD

    pack and unpack are used for converting between encodings. pack encodes. unpack decodes.

Re: pack peculiarity
by revdiablo (Prior) on Dec 26, 2003 at 23:43 UTC

    !1 has already answered the question, but I thought it might use a bit of clarification. The thing that's being printed, ABCD, is the encoded form of that number. The fact that it shows up as ABCD can be considered as nothing more than a random coincidence (not that it necessarily is a random coincidence). The important part is that the bits are getting packed into a more compact representation, that just happens to show up as some letters when printed.

Re: pack peculiarity
by pg (Canon) on Dec 27, 2003 at 02:23 UTC

    I made a little piece of code to help you understanding what's going on:

    $number = 1145258561; print pack( "l", $number ), "\n"; do { print chr($number % 0x100); $number = $number >> 8; } until (!$number);
      To clarify a little bit (I hope), Perl's strings are a string of bytes, which may or may not be a string of printable characters. When Perl is asked to print a string, it just outputs all of the bytes in the string, one after the other. In this case, the bytes are 0x41 0x42 0x43 0x44, which happen to be the ASCII character codes for ABCD.

      Update: As pg mentions below, this terminology might be wrong in the face of Unicode. If, for the sake of this example, you temporarily pretend Unicode doesn't exist, hopefully this comment will still shed some additional light. :-)

        I like the infomation you added. But you may want to reconsider your statement that "Perl's strings are a string of bytes", as there are actually two semantics: bytes and characters, especially when you have unicode in mind. (Obviously the actual storage is a stream of octets, but there are two different semantics to interpret. There is a very subtle difference in the concept of octet and byte, and probably you noticed that those two words are used very carefully nowadays in all kinds of standards.)

        I know what you meant, just thought that that pariticular statement might be a little bit too generalized.

Re: pack peculiarity
by bl0rf (Pilgrim) on Dec 28, 2003 at 00:10 UTC
    Thanks to everyone for their feedback, I now undersand much better what pack() does ( unfortunately better doesnt mean well... ). The thing that puzzled me was addressed in revdiablo's comment, I was suspecting that ABCD was just a convenient coincidence but I had to make sure (i.e. ask someone who knows).