negate, !!$a, $a!!, flip-flop
Hello! Is there a shorter way to write $a = ! $a, please? Something analogous to ++ and -- operators like $a !! or !! $a would negate the variable $a and return its previous or new value respectively. Best regards HG -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
Hans Ginzel wrote: Hello! Hello, Is there a shorter way to write $a = ! $a, please? No. John -- Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction. -- Albert Einstein -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
On 09/09/2013 11:00, Hans Ginzel wrote: Is there a shorter way to write $a = ! $a, please? perl -le ' my @a = (undef, @ARGV); for $a (@a) { my @r; push @r, "$a:"; for (1..3) { push @r, $a^=1; # <-- } print "@r"; } ' 0 1 2 3 -1 : 1 0 1 0: 1 0 1 1: 0 1 0 2: 3 2 3 3: 2 3 2 -1: 4294967294 4294967295 4294967294 -- Ruud -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
On Mon, 09 Sep 2013 11:00:31 +0200 Hans Ginzel wrote: > Is there a shorter way to write $a = ! $a, please? Why? -- Don't stop where the ink does. Shawn -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
On Tue, Sep 10, 2013 at 08:29:00AM -0400, Shawn H Corey wrote: > On Mon, 09 Sep 2013 11:00:31 +0200 > Hans Ginzel wrote: > > > Is there a shorter way to write $a = ! $a, please? > > Why? Because it's the sort of thing one might expect Perl to provide. I know that I have thought that before. ^= 1 is close, but you really want something that works on truthiness rather than bits, and xor= doesn't exist. However, since people will tell you off for using $a anyway, I suggest using $| instead, and then the operation you are looking for is $|-- $ perl -E 'say $|-- for 1 .. 5' 0 1 0 1 0 [ If it's not obvious, my tongue was in my cheek for half of this post. ] -- Paul Johnson - p...@pjcj.net http://www.pjcj.net -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
On 09/10/13 14:59, David Christensen wrote: Assuming canonical boolean values, post-invert semantics (save the new value into another variable) ... Pre-invert semantics (save the old value into another variable) ... Oops -- it looks like I got my pre- and post- backwards... And, dropping the save old idiom: ($var = $old = $var) ^= 1 into the middle of expression would yield the new value, which would be wrong... David -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
September 10, 2013 06:15 Hans Ginzel wrote: > Is there a shorter way to write $a = ! $a, please? > Something analogous to ++ and -- operators like $a !! or !! $a would > negate the variable $a and return its previous or new value > respectively. I don't believe Perl has boolean pre-invert or post-invert unary operators. You might be able to build something with objects and operator overloading, but that would mean overloading existing operators. Adding entirely new operators could require hacking the Perl source code (?). On 09/10/13 04:14, Dr.Ruud wrote: $a^=1 The bitwise xor-equals binary operator is an interesting suggestion. Yes, it inverts the boolean sense of variables containing canonical boolean values (undef, empty string, numerical zero, and numerical one). But, thinking in boolean and applying this operator to other kinds of values may be confusing (see script and output, below). Assuming canonical boolean values, post-invert semantics (save the new value into another variable) can be can be obtained with assignment: $new = ($var ^= 1) It appears that xor-equals has higher precedence than assignment, so the parentheses are not required: $new = $var ^= 1 Pre-invert semantics (save the old value into another variable) can be obtained with multiple assignment, protected within parentheses, so that xor-equals operates on the correct lvalue: ($var = $old = $var) ^= 1 Note that the following will make a copy and then invert the copy. leaving the original untouched: ($varn = $var) ^= 1 HTH, David 2013-09-10 14:27:36 dpchrist@desktop ~/sandbox/perl $ cat xor-equal.pl #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my ( $t,$f,$u,$e,$z,$o,$i,$n,$s); my ($newt, $newf, $newu, $newe, $newz, $newo, $newi, $newn, $news); my ($oldt, $oldf, $oldu, $olde, $oldz, $oldo, $oldi, $oldn, $olds); sub dump_new { Data::Dumper->Dump( [$newt, $newf, $newu, $newe, $newz, $newo, $newi, $newn, $news], [qw(newt newf newu newe newz newo newi newn news)]); } sub dump_old { Data::Dumper->Dump( [$oldt, $oldf, $oldu, $olde, $oldz, $oldo, $oldi, $oldn, $olds], [qw(oldt oldf oldu olde oldz oldo oldi oldn olds)]); } sub dump_var { Data::Dumper->Dump([$t, $f, $u, $e, $z, $o, $i, $n, $s], [qw(t f u e z o i n s)]); } sub reset_var { $t = (1 == 1); # true $f = (1 != 1); # false $u = undef; # undefined value $e = '';# empty string $z = 0; # zero $o = 1; # one $i = 255; # integer $n = 3.141592653589793238462; # double $s = "Just another Perl hacker"; # string } sub save_new { $newt = $t ^= 1; $newf = $f ^= 1; $newu = $u ^= 1; $newe = $e ^= 1; $newz = $z ^= 1; $newo = $o ^= 1; $newi = $i ^= 1; $newn = $n ^= 1; $news = $s ^= 1; } sub save_old { ($t = $oldt = $t) ^= 1; ($f = $oldf = $f) ^= 1; ($u = $oldu = $u) ^= 1; ($e = $olde = $e) ^= 1; ($z = $oldz = $z) ^= 1; ($o = $oldo = $o) ^= 1; ($i = $oldi = $i) ^= 1; ($n = $oldn = $n) ^= 1; ($s = $olds = $s) ^= 1; } reset_var(); print "### reset values ###\n", dump_var(); save_new(); print "### xor-equals, save new values ###\n", dump_var(), dump_new(); save_new(); print "### again ###\n", dump_var(), dump_new(); reset_var(); print "### reset values ###\n", dump_var(); save_old(); print "### xor-equals, save old values ###\n", dump_var(), dump_old(); save_old(); print "### again ###\n", dump_var(), dump_old(); 2013-09-10 14:27:38 dpchrist@desktop ~/sandbox/perl $ perl xor-equal.pl ### reset values ### $t = 1; $f = ''; $u = undef; $e = ''; $z = 0; $o = 1; $i = 255; $n = '3.14159265358979'; $s = 'Just another Perl hacker'; Argument "" isn't numeric in bitwise xor (^) at xor-equal.pl line 43. Argument "Just another Perl hacker" isn't numeric in bitwise xor (^) at xor-equal.pl line 48. ### xor-equals, save new values ### $t = 0; $f = 1; $u = 1; $e = 1; $z = 1; $o = 0; $i = 254; $n = 2; $s = 1; $newt = 0; $newf = 1; $newu = 1; $newe = 1; $newz = 1; $newo = 0; $newi = 254; $newn = 2; $news = 1; ### again ### $t = 1; $f = 0; $u = 0; $e = 0; $z = 0; $o = 1; $i = 255; $n = 3; $s = 0; $newt = 1; $newf = 0; $newu = 0; $newe = 0; $newz = 0; $newo = 1; $newi = 255; $newn = 3; $news = 0; ### reset values ### $t = 1; $f = ''; $u = undef; $e = ''; $z = 0; $o = 1; $i = 255; $n = '3.14159265358979'; $s = 'Just another Perl hacker'; Argument "" isn't numeric in bitwise xor (^) at xor-equal.pl line 55. Argument "Just another Perl hacker" isn't numeric in bitwise xor (^) at xor-equal.pl line 60. ### xor-equals, save old values ### $t = 0; $f = 1; $u = 1; $e = 1; $z = 1; $o = 0; $i = 254; $n = 2; $s = 1;
Re: negate, !!$a, $a!!, flip-flop
On Tue, 10 Sep 2013 17:04:07 -0700 David Christensen wrote: > scalar ($v ^= 1, !$v) ( ! ( $v ^= 1 )) or do { $v = ! $v; !$v } TIM TOW TDI ;) -- Don't stop where the ink does. Shawn -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
beginners: Here's a second try at using bitwise xor-equals to implement boolean pre- and post-invert operations for variables containing canonical boolean values (undef, empty string, zero, and one). The pre-invert semantics case (invert, then use) uses the bitwise xor-equals operator and one, as before, but I found that parentheses are sometimes required: ($v ^= 1) The post-invert semantics case (use, then invert) can be obtained by using the "scalar" operator on a parenthesized list: scalar ($v ^= 1, !$v) RTFM "perldoc -f scalar": scalar EXPR ... Because "scalar" is unary operator, if you accidentally use for EXPR a parenthesized list, this behaves as a scalar comma expression, evaluating all but the last element in void context and returning the final element evaluated in scalar context. This is seldom what you want. The first list element inverts and saves the value of $v, the second list element evaluates to the inverse of the inverse, which is the same (in boolean context) as the original, and "scalar" returns that. This is what we want. HTH, David 2013-09-10 16:31:14 dpchrist@desktop ~/sandbox/perl $ cat xor-equal2.pl #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $v; sub dump_v { Data::Dumper->Dump([$v], [qw(v)]) }; $v = undef; print dump_v(); print 'pre-invert is ', ($v ^= 1) ? 'T' : 'F', "\n"; print dump_v(); print 'pre-invert is ', ($v ^= 1) ? 'T' : 'F', "\n"; print dump_v(); $v = undef; print dump_v(); print 'post-invert is ', scalar ($v ^= 1, !$v) ? 'T' : 'F', "\n"; print dump_v(); print 'post-invert is ', scalar ($v ^= 1, !$v) ? 'T' : 'F', "\n"; print dump_v(); 2013-09-10 16:31:17 dpchrist@desktop ~/sandbox/perl $ perl xor-equal2.pl $v = undef; pre-invert is T $v = 1; pre-invert is F $v = 0; $v = undef; post-invert is F $v = 1; post-invert is T $v = 0; -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
On Mon, Sep 9, 2013 at 6:00 AM, Hans Ginzel wrote: > Hello! > > Is there a shorter way to write $a = ! $a, please? > > Something analogous to ++ and -- operators like $a !! or !! $a would negate > the variable $a and return its previous or new value respectively. > > Best regards Not really. But you can toy around with operator overloading to make it work, or abuse prototypes and do this: sub b (*) { my $o = $_[0]; $_[0] = !!$_[0]; $o } # b for bool, sub nb (*) { my $o = $_[0]; $_[0] = !$_[0]; $o } # nb for not bool. 100% maintainable and understandable my $v = 10; nb $v; say $v; nb $v; say $v There might be more magical ways to do this (read: Devel::CallParser), but you'll have to dig for those yourself.
Re: negate, !!$a, $a!!, flip-flop
On Mon, Sep 9, 2013 at 5:00 AM, Hans Ginzel wrote: > Hello! > > Is there a shorter way to write $a = ! $a, please? > > Something analogous to ++ and -- operators like $a !! or !! $a would negate > the variable $a and return its previous or new value respectively. > It sounds like what you're requesting, specifically, is to have an operator which modifies $a in place (such as ++ and --). Since Perl doesn't have one of those you need to use an assignment operator. Since you want to return the logical opposite of $a you need a modifying assignment operator. I think you found the shortest possible as long as you remove the extra whitespace. - Casey
Re: negate, !!$a, $a!!, flip-flop
David Christensen wrote: September 10, 2013 06:15 Hans Ginzel wrote: > Is there a shorter way to write $a = ! $a, please? > Something analogous to ++ and -- operators like $a !! or !! $a would > negate the variable $a and return its previous or new value > respectively. I don't believe Perl has boolean pre-invert or post-invert unary operators. You might be able to build something with objects and operator overloading, but that would mean overloading existing operators. Adding entirely new operators could require hacking the Perl source code (?). On 09/10/13 04:14, Dr.Ruud wrote: $a^=1 The bitwise xor-equals binary operator is an interesting suggestion. Yes, it inverts the boolean sense of variables containing canonical boolean values (undef, empty string, numerical zero, and numerical one). But, thinking in boolean and applying this operator to other kinds of values may be confusing (see script and output, below). Assuming canonical boolean values, post-invert semantics (save the new value into another variable) can be can be obtained with assignment: $new = ($var ^= 1) It appears that xor-equals has higher precedence than assignment, so the parentheses are not required: $new = $var ^= 1 xor-equals IS assignment and has the same precedence as assignment: perldoc perlop [SNIP] Assignment Operators "=" is the ordinary assignment operator. Assignment operators work as in C. That is, $a += 2; is equivalent to $a = $a + 2; although without duplicating any side effects that dereferencing the lvalue might trigger, such as from tie(). Other assignment operators work similarly. The following are recognized: **=+=*=&=<<=&&= -=/=|=>>=||= .=%=^= //= x= Although these are grouped by family, they all have the precedence of assignment. John -- Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction. -- Albert Einstein -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
On 09/10/13 20:01, John W. Krahn wrote: xor-equals IS assignment and has the same precedence as assignment: Thanks! David -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: negate, !!$a, $a!!, flip-flop
Hans Ginzel wrote: Hello! Hello, Is there a shorter way to write $a = ! $a, please? Something analogous to ++ and -- operators like $a !! or !! $a would negate the variable $a and return its previous or new value respectively. You can do that if you use a reference to a scalar like this: $ perl -le'my $x = do { \vec my $y, 0, 1 }; for ( 1 .. 6 ) { print ++$$x }' 1 0 1 0 1 0 $ perl -le'my $x = do { \vec my $y, 0, 1 }; for ( 1 .. 6 ) { print --$$x }' 1 0 1 0 1 0 $ perl -le'my $x = do { \vec my $y, 0, 1 }; for ( 1 .. 6 ) { print $$x++ }' 0 1 0 1 0 1 $ perl -le'my $x = do { \vec my $y, 0, 1 }; for ( 1 .. 6 ) { print $$x-- }' 0 1 0 1 0 1 I used the do {} block so that $y doesn't leak out into the rest of the program, but you can omit it if you want. John -- Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction. -- Albert Einstein -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/