If you need to create a set of bit flags (like O_CREAT, O_RDWR, O_EXCL, etc.), then this compile-time pragma is just dandy. It keeps a running track of the last value given, so you don't need to worry about duplicates. If you do want to change the value, you can send an argument denoting the starting value (must be a power of 2) or the starting power. (This module is also available at http://www.pobox.com/~japhy/modules/bitflags/bitflags.pm)

Here is the module's POD:
NAME
     bitflags - Perl module for generating bit flags

SYNOPSIS
       use bitflags qw( ALPHA BETA GAMMA DELTA );
       use bitflags qw( EPSILON ZETA ETA THETA );

       use bitflags qw( :start=2 BEE CEE DEE EEE EFF GEE );

       use bitflags qw( :start=^2 FOUR EIGHT SIXTEEN );

DESCRIPTION
     The bitflags module allows you to form a set of unique
     bit flags, for ORing together.  Think of the O_
     constants you get from Fcntl... that's the idea.

     Successive calls remember the previous power used, so
     you don't have to set a starting number, or declare
     all the constants on one line.

     If you do want to set a starting value, use the :start
     flag as the first argument in the import list.  If the
     flag is :start=NNN, where NNN is some positive
     integer, that value is checked to ensure it's a power
     of two, and that value is used as the starting value.
     If it is not a power of two, the program will croak.
     If the flag is :start=^NNN, where NNN is some positive
     integer, that value is the power of two to start with.

     Implementation

     The flags are created as ()-prototyped functions in the
     caller's package, not unlike the constant pragma.

AUTHOR
     Jeff "japhy" Pinyan.

     URL: http://www.pobox.com/~japhy/

     Email: japhy@pobox.com, PINYAN@cpan.org

     CPAN ID: PINYAN

     Online at: japhy on #perl on DALnet and EFnet.  japhy
     at http://www.perlguru.com/.  japhy at
     http://www.perlmonks.org/.  "Coding With Style"
     column at http://www.perlmonth.com/.
package bitflags; use strict; my $i = .5; sub import { my $self = shift; my $caller = (caller)[0]; if ($_[0] =~ /^:start=(\^?)(\d+)$/) { if ($1) { $i = 2 ** ($2-1) } elsif ($2 & ($2 - 1)) { require Carp; Carp::croak("$2 is not a power of two"); } else { $i = $2/2 } shift; } no strict 'refs'; for (@_) { my $j = ($i *= 2); *{"${caller}::$_"} = sub () { $j }; } } 1;

Replies are listed 'Best First'.
RE: bit flag generator
by Adam (Vicar) on Jul 20, 2000 at 23:16 UTC
    That's interesting, but why didn't you just use vec()?
    my $bitflags = 0; #all off. vec( $bitflags, 0, 1 ) = 1; # Set the first bit. print "First bit is set\n" if( vec( $bitflags, 0, 1 ) ); vec( $bitflags, 1, 1 ) = 1; # Set the second bit. print "Second bit is set\n" if( vec( $bitflags, 1, 1 ) ); vec( $bitflags, 0, 1 ) = 0; # UnSet the first bit. print "First bit is set\n" if( vec( $bitflags, 0, 1 ) ); print "First bit is off\n" if( !vec( $bitflags, 0, 1 ) ); # and so on...
      vec() is not a user-friendly function, in all honesty. Bit::Vector makes it easier, but it's rarely that you have to deal with this matter. It's also much nicer to have NAMES for your bits (hmm, that sentence doesn't sound quite right).