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

Boolean counter?

by DreamT (Pilgrim)
on Dec 07, 2009 at 07:57 UTC ( [id://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?

Replies are listed 'Best First'.
Re: Boolean counter?
by Corion (Patriarch) on Dec 07, 2009 at 08:06 UTC

    The xor operator will do what you want:

    $counter = $counter xor 1

    or

    $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 ikegami (Patriarch) 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 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
    $toggle=$toggle?0:1;
    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 GrandFather (Saint) on Dec 07, 2009 at 08:58 UTC

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

    print $|-- for 1 .. 4;

    Prints:

    1010

    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 Ratazong (Monsignor) on Dec 07, 2009 at 12:19 UTC
    Just to show that you can make a lot with "lookup-tables" ;-)

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

    Rata

      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 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 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 vitoco (Hermit) 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;

        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;
        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.
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 hdb (Monsignor) on Mar 04, 2015 at 13:07 UTC

    I cannot resist. You can also use a closure, every time you call it you get 0 or 1 alternatingly. You can create as many independent toggles as you want.

    use strict; use warnings; sub create_toggle { my $flag = 0; return sub { $flag = 1-$flag } # your favorite method here } my $toggle = create_toggle; print $toggle->()."\n" for 1..10;

    UPDATE: ...or like this

    use strict; use warnings; { package Toggler; sub new { my $flag = 0; return sub { $flag = 1-$flag } } } my $toggle = new Toggler; print $toggle->()."\n" for 1..10;
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

      Your idea works the following way - even if it doesn't look as elegant any more:

      $toggle = -1 * ($toggle - 0.5) + 0.5;
      Rata (loving this thread)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (6)
As of 2024-04-19 06:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found