tags:

views:

78

answers:

3

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.

A: 

Thinking aloud here - will bitwise operators help? Like doing a xor on two identical strings will give a bitstring with everything set to 0.

http://perldoc.perl.org/perlop.html#Bitwise-String-Operators

deepakg
xor would be a great equality test independent of locale, actually - nice idea - would not be useful for less than/greater than however.
PP
+4  A: 

Expand, then contract. Compare for example the hex representation of your structures, which only uses ASCII characters and cannot run afoul of the locale problem you mention.

unpack('H*', $first) cmp unpack('H*', $second)
daxim
+5  A: 

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
Greg Bacon
Does "no locale" only apply within the closure? If there is a locale that applies outside the closure will it still apply to any code below the closure?
PP
@PP Yes, the `locale` pragma is lexical: it's in effect only inside its enclosing block.
Greg Bacon