Re: Logical Not not working!!!
by james2vegas (Chaplain) on Aug 20, 2010 at 19:45 UTC
|
Booleans in Perl are not 1s and 0s, they are 0, '0', "", undef as "FALSE", and everything else as "TRUE". So negating "1" (TRUE) gives you "" (FALSE). If you need it to be a number, do something like $false_value += 0 or my $number = $false_value ? 1 : 0 | [reply] [d/l] [select] |
Re: Logical Not not working!!!
by kennethk (Abbot) on Aug 20, 2010 at 19:49 UTC
|
Some reading that might make this behavior more clear is Scalar values from perldata.
In order to have its ability to silently work with strings, numbers and booleans without explicit coding of intent, Perl actually stores appropriate values internally. When you use the expression $var = !$var;, you set the variable to FALSE and clear out any numbers or strings associated with it. When you then ask it to print $var, Perl checks what it knows about the value. Since you want a string and the value is FALSE, it outputs "", the false string. Hence, after toggling, you actually have @array = ('1', '', '1'); You can get your expected behavior if you numify, for example with the code $_ += 0 foreach @array;. This will tell Perl to store a numerical value, which it will check before output.
As a side note, you should pick visible characters as delimiters when checking what you are actually outputting. If you'd used print "<$_>"; for example, you would have gotten the much more obvious <1><><1> as output.
| [reply] [d/l] [select] |
|
|
Thanks for a very clear explanation and advice about the log..I think its is a profound concept for a beginner..I am glad I asked
| [reply] |
|
|
| [reply] |
Re: Logical Not not working!!!
by ikegami (Patriarch) on Aug 20, 2010 at 20:21 UTC
|
Why do you expect zero specifically?
The false value typically returned by Perl is a special value that's "" when treated as a string and 0 when treated as a number.
$ perl -wle'my $x = !1; print "".$x; print 0+$x;'
0
$ perl -wle'my $x = ""; print "".$x; print 0+$x;'
Argument "" isn't numeric in addition (+) at -e line 1.
0
$ perl -wle'my $x = 0; print "".$x; print 0+$x;'
0
0
| [reply] [d/l] |
|
|
I am using it check the results later in the code..but thanks guys!!
| [reply] |
|
|
You apparently have a boolean, so checking involes using
if (!$value)
instead of
if ($value == 0)
Mind you, the latter would work fine with !1 as well, so I don't see the problem.
If need to format it to print it, you can use the conditional operator.
print("value = ", $value?"true":"false", "\n");
But there's no need to format it until it's time to output it. | [reply] [d/l] [select] |
Re: Logical Not not working!!!
by JavaFan (Canon) on Aug 20, 2010 at 22:21 UTC
|
If you want your results to be numbers, don't apply boolean logic to them. Use numbers. Assuming you know @array is filled with 0 and 1, you could do:
@array = (0, 1, 0);
@array = map {1 - $_} @array;
say "@array"; # 1 0 1
I guess in Perl6, the middle line can be written as @array = 1 >>-<< @array and be considered a vast improvement. | [reply] [d/l] [select] |
Re: Logical Not not working!!!
by CountZero (Bishop) on Aug 21, 2010 at 07:35 UTC
|
Rather than using a C-style for-loop, a more Perlish way of dealing with the array is as follows: use strict;
use warnings;
use Data::Dumper;
my @array = (1,0,1);
for my $item (@array) {
$item = !$item + 0;
}
print Dumper(\@array);
$item becomes an alias for each element of @array: so whatever you do to $item you really do that to the actual element of the array.Update: or even shorter, but perhaps less legible:$_=!$_+0 for @array;
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James
| [reply] [d/l] [select] |
Re: Logical Not not working!!!
by locked_user sundialsvc4 (Abbot) on Aug 20, 2010 at 19:45 UTC
|
Not sure why you have three outputs on the first line and only two on the second, but nevermind. Just use $array[$i] = ($array[$i] ? 0 : 1);
This is the sort of “problem” that just is not worth pulling out hair over. “Don’t bother to ask Why. Just write Something That Works, and that is reasonably clear to you and to your successor, and move along.”
| |
|
|
Thats the output..its not printing anything when i try to print !1, but ya..I think the james2vegas's explanation that 1 is negating to " " makes sense...Thanks for replying
| [reply] |
Re: Logical Not not working!!!
by BrowserUk (Patriarch) on Aug 21, 2010 at 07:53 UTC
|
print @a;;
1 1 0 0 1 1 0 0 0 0 0 1 1 1 0 0
$_ ^= 1 for @a;;
print @a;;
0 0 1 1 0 0 1 1 1 1 1 0 0 0 1 1
| [reply] [d/l] |
Re: Logical Not not working!!!
by Generoso (Prior) on Aug 20, 2010 at 22:12 UTC
|
#!/usr/bin/perl
#
use strict;
use warnings;
while (<DATA>) { print;
chomp;
foreach (split /,/){print $_ ? "0," : "1,";}
print "\n";
}
__DATA__
0,1,1
1,1,0
0,1,0
1,0,0
1,1,1
| [reply] [d/l] |
Re: Logical Not not working!!!
by Anonymous Monk on Aug 21, 2010 at 04:17 UTC
|
Here's a perlish way to write that snippit
use strict;
use warnings;
my @foo = (0, 1, 0);
print " \@foo: @foo\n";
$_ = !$_?1:0 for @foo;
print "!\@foo: @foo\n";
| [reply] [d/l] |
Re: Logical Not not working!!!
by Ratazong (Monsignor) on Aug 21, 2010 at 10:25 UTC
|
Just for completeness: the following node lists a lot of additional ways of toggeling between 0 and 1: Boolean counter?
| [reply] |