Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Boolean counter?

by DreamT (Pilgrim)
on Dec 07, 2009 at 07:57 UTC ( #811439=perlquestion: print w/ replies, xml ) Need Help??
DreamT has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I'd like to have a counter that is boolean, so when you increment it, it should either become 0 or 1, based on it's previous value. I can do it like this:
if ($Counter == 0) { $Counter = 1; } else { $Counter = 0; }
, but I'd like to do the above in a more elegant way. Is it possible?

Comment on Boolean counter?
Download Code
Re: Boolean counter?
by Corion (Pope) on Dec 07, 2009 at 08:06 UTC

    The xor operator will do what you want:

    $counter = $counter xor 1


    $counter ^= 1

    (tested with perl -wle "print $counter ^=1 for 1..3")

      I agree that the XOR solution is perfectly correct, but why use that instead of NOT? Isn't

       $counter = ! $counter;

      easier to read? That said, I have to admit that I like the snazzyness of the in place ^= syntax. It is hard to get more concise than that.

      - doug

        The difference is that $toggle ^= 1; leaves you with a number (0 or 1) while $toggle = !$toggle; leaves you with a boolean.

        Honestly, it sounds like the OP wants a boolean, so the easier to read negation should be used. If he wants to display the boolean, that's an outputting formatting issue to be resolved then.

Re: Boolean counter?
by Utilitarian (Vicar) on Dec 07, 2009 at 08:06 UTC
    What you want is not a counter but a toggle, shortened using the ternary operator, but not sure if it's more elegant
    Edit...In fact Corion's solution above is way better.

    print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."
Re: Boolean counter?
by ikegami (Pope) on Dec 07, 2009 at 08:08 UTC
    For starters,
    if ($toggle) { $toggle = 0; } else { $toggle = 1; }

    can be written as

    $toggle = $toggle ? 0 : 1;

    And if you wanted a bitwise toggle, you could do

    $toggle ^= 1;

    But you asked for boolean, so you want the even simpler:

    $toggle = !$toggle;
Re: Boolean counter?
by eye (Chaplain) on Dec 07, 2009 at 08:18 UTC
    One more way...

    $toggle = 1 - $toggle;
    This lacks elegance since it needs to start at 0 or 1, but it is simple.
Re: Boolean counter?
by moritz (Cardinal) on Dec 07, 2009 at 08:21 UTC
    You can just use ++ to increment your counter, but when you ask for its value use $counter % 2 instead of the counter itself.

    Or if you're not interested in the numeric value 0, but rather that it's a false value, you can also use this update step:

    $counter = !$counter;
      Or if you do want the numerical value:
      $counter = !$counter || 0;
Re: Boolean counter?
by GrandFather (Cardinal) on Dec 07, 2009 at 08:58 UTC

    Of course if you want obscure you can use $|--. Consider:

    print $|-- for 1 .. 4;



    Although I wouldn't recommend it in a context where you wish to win friends and influence people among the bossing classes.

    True laziness is hard work
Re: Boolean counter?
by JavaFan (Canon) on Dec 07, 2009 at 12:00 UTC
    Just to prove you can use trigs to solve almost anything:
    $counter = int cos $counter * atan2(1, 0);
Re: Boolean counter?
by Ratazong (Prior) on Dec 07, 2009 at 12:19 UTC
    Just to show that you can make a lot with "lookup-tables" ;-)

    $counter = (1, 0)[$counter];


      Just to make "lookup-tables" prettier. ;-)

      $counter = [ 1 => 0 ] -> [ 1 <= $counter ];

        ug, you create two variables every time you toggle it (one of which is an array!), and you rely on the undocumented values of <= returns. And the latter doesn't help make it prettier at all!
Re: Boolean counter?
by vitoco (Pilgrim) on Dec 07, 2009 at 12:47 UTC

    Two more approaches:

    - Using hashes:

    my %Next = ( 0 => 1, 1 => 0); my $Counter = 0; #... $Counter = $Next{$Counter};

    - Decreasing instead of increasing:

    $Counter = abs --$Counter;
      $Counter = - --$Counter;
        The behaviour of that is actually not defined. You may end up with $Counter being -1, or with purple daemons coming out of your USB port, ready to chew off your fingers.

        Don't modify a variable that you're using elsewhere in an expression. At best, it's unclear. At worse, the result is undefined.

        $toggle = - --$toggle;
        should be
        $toggle = -( $toggle - 1 );
        which can be shortened to previously mentioned
        $toggle = 1 - $toggle;
Re: Boolean counter?
by rowdog (Curate) on Dec 07, 2009 at 22:11 UTC

    I tend to use $toggle *= -1;

    Update: I stand corrected, thanks LanX. I often use that for alternating rows but it's wrong here.

      well it's a toggle but can't be used as boolean as the OP wanted , since 0*-1=0

      Cheers Rolf

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://811439]
Approved by lidden
Front-paged by lidden
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (15)
As of 2014-07-29 15:38 GMT
Find Nodes?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:

    Results (220 votes), past polls