Search code examples
perlbitbitvectorvec

Empty `vec()` is not False


Consider this example:

#!/usr/bin/env perl

my $vec0;

# set the first bit of vec0 to false
vec($vec0, 0, 1) = 0;

print "vec0 is " . length($vec0) . " bytes long\n";

if ($vec0) {
  # what
  print "vec0 is True!\n";
}

A vec used in evaluation seems to (almost) always be True - this is because a vec is really a string, and so $vec0 is a string containing "\0" which is not False according to Perl: only strings "" and "0" are False.

(aside: this is False, despite being non-zero:

vec($vec0, 5, 1) = 1;
vec($vec0, 4, 1) = 1;

because 0x30 is the ASCII code for 0)

Fine: what is the "correct" way to check for an "empty" vector (i.e. all bits set to 0)? Count bits with unpack, regex test m/^\0*$/, "normalize" all vectors by chopping empty bytes off the end? This seems like it should be a solved problem... and why does Perl not treat vec magically for true/false?


Solution

  • The following is probably the fastest approach without external C code:

    $vec0 !~ tr/\x01-\xFF//   # True if "empty".
    
    $vec0 =~ tr/\x01-\xFF//   # True if not "empty".