Search code examples
perlcomparepack

How do I compare packed values in Perl?


I want to use the pack() function in Perl to encode some data. Then I want to compare my packed structure to another packed structure. I want this compare to be on the byte values of this packed structure.

According to the documentation, cmp uses the current locale to determine how to compare strings. But I don't want any intelligence applied to the comparison. I want whatever is closest to a memcmp(). Obviously I cannot use <=> for comparing my packed objects as they are not numbers.

What is the best way to compare packed strings in Perl?

Sidenote: I have been reading this article on efficient sorting in Perl which notes that the plain sort function uses a memcmp-like algorithm for comparing structures. I'm wondering how to achieve such a comparison without having to use sort.


Solution

  • Disable locale considerations for the block and use cmp as usual:

    sub mycmp {
      no locale;
      $_[0] cmp $_[1];
    }
    

    The perlop documentation provides

    lt, le, ge, gt and cmp use the collation (sort) order specified by the current locale if use locale is in effect. See perllocale.

    and then in perllocale

    The default behavior is restored with the no locale pragma, or upon reaching the end of block enclosing use locale.

    For example, running

    my($one,$two) = map pack("N", $_) => 1, 2;
    say mycmp($one, $two);
    say mycmp($two, $one);
    

    outputs

    -1
    1