I get some code It works but don't understan this part !$dump_done...
my $dump_done = 0;
foreach my $line(keys %results){
if ($results{$line} == 1 and !$dump_done) {
print Dump($post);
$dump_done = 1;
}
}
! is the Logical NOT operator. It will return the negation of $dump_done. If $dump_done contains 0, the negation will give you 1:
my $dump_done = 0;
print !$dump_done; # Prints 1
This is valid, because in Perl any non-zero value is considered true and 0 is considered false.
You can try out this snippet:
if (5) {
print "Hello"; # Will be executed.
}
The ! character in most programming languages stands for NOT, it's the negation.
If the value of your variable $dump_done is still zero, when you test $dump_done it will returns FALSE (0). If you negate this expression, you get a TRUE expression (!= 0).
See Truth and Falsehood
Related
Please explain me what is hapenning in line 3 of this code.
for my $i (0 .. $dim) {
for my $j (0 .. $dim) {
$adj->[$i][$j] = $adj->[$i][$j] ? [$j] : [];
The code loops over two dimensions in an array reference $adj. Presumably, $dim is the dimension, and $i and $j iterate over a list of numbers from 0 to $dim, e.g. 0,1,2,3,4,5.
For each combination of numbers, the value of that array element is checked for trueness, and is assigned a new value. If the value is false, it is assigned an array ref containing the index $j, otherwise an empty array ref [].
The conditional operator is used here, with the basic syntax
CONDITION ? FOO : BAR
if CONDITION then FOO else BAR
Presumably, the array ref $adj is supposed to contain array references, which is why it can simply check for trueness as a shortcut for defined $adj->[$i][$j].
This is the ternary operator, aka conditional operator.
If $adj->[$i][$j] is 0 (or undefined) then [] is assigned to $adj->[$i][$j], in the other cases $adj->[$i][$j] is assigened to $adj->[$i][$j].
perlop has this quote:
Ternary "?:" is the conditional operator, just as in C. It works much like an if-then-else.
If the argument before the ? is true, the argument before the : is returned, otherwise the argument after the : is returned.
for my $i (0 .. $dim) {
for my $j (0 .. $dim) {
Above for loops will itrate through the arry with dimension $dim x $dim
$adj->[$i][$j] = $adj->[$i][$j] ? [$j] : [];
if $adj->[$i][$j] is zero, then assign [] to $adj->[$i][$j] else assign $j (column value)
As the title says, perl adds dummy elements to arrays after inquiries to not existing elements. Array size grows after the inquiry. Illustration to the behaviour:
my $rarr;
$rarr->[0][0] = 'S';
$rarr->[0][1] = 'MD';
$rarr->[1][0] = 'S';
$rarr->[1][1] = 'PRP';
my $crulesref;
$crulesref->[0] = $rarr;
check_rule('aa', 0);
if($rarr->[3][0] == 'M'){ # just check a not existing element
print "m\n";
}
check_rule('bb', 0);
if($rarr->[5][0] == 'M'){ # again: just check a not existing element
print "m\n";
}
check_rule('cc', 0);
sub check_rule($$)
{
my ($strg,$ix) = #_;
my $aref = $crulesref->[$ix];
my $rule_size = #$aref;
{print "-----$strg aref:$aref rs:$rule_size aref:'#$aref'\n";
for(my $t1 = 0; $t1 <$rule_size; $t1++){
print "t1:$t1 0:$aref->[$t1][0] 1:$aref->[$t1][1]\n";
}
}
}
The result of the run is:
en#en-desktop ~/dtest/perl/forditas/utf8_v1/forditas/test1 $ perl v15.pl
-----aa aref:ARRAY(0x90ed8c8) rs:2 aref:'ARRAY(0x9106cac) ARRAY(0x9106d24)'
t1:0 0:S 1:MD
t1:1 0:S 1:PRP
m <-------------- finds the non existing
-----bb aref:ARRAY(0x90ed8c8) rs:4 aref:'ARRAY(0x9106cac) ARRAY(0x9106d24) ARRAY(0x9107508)'
t1:0 0:S 1:MD
t1:1 0:S 1:PRP
t1:2 0: 1: <-- undesired dummy due to inquiry
t1:3 0: 1: <-- undesired dummy due to inquiry
m <-------------- finds the non existing
-----cc aref:ARRAY(0x90ed8c8) rs:6 aref:'ARRAY(0x9106cac) ARRAY(0x9106d24) ARRAY(0x9107904) ARRAY(0x9107508) ARRAY(0x910e860)'
t1:0 0:S 1:MD
t1:1 0:S 1:PRP
t1:2 0: 1: <-- undesired dummy due to inquiry
t1:3 0: 1: <-- undesired dummy due to inquiry
t1:4 0: 1: <-- undesired dummy due to inquiry
t1:5 0: 1: <-- undesired dummy due to inquiry
Is there no other way to avoid this than to ask before each inquiry, if the inquired element exists? I try to increase speed, and these inquiries slow the code down, and make it less easy to read.
Thanks in advance for useful hints.
This is autovivification that you are seeing. If you access the memory of $ref->[3][0] even with just a check:
if ($ref->[3][0] eq 'M' )
Then first $ref->[3] must exist before its element number zero can be checked, so it is created via autovivification. You need to first check if $ref->[3] exists or is defined to avoid creating it.
if (defined($ref->[3]) && $ref->[3][0] eq 'M')
Also, you should always use:
use strict;
use warnings;
Then you would see the warnings
Argument "M" isn't numeric in numeric eq (==) at ...
Use of uninitialized value in numeric eq (==) at ...
The if-clause gives a false positive here because the string 'M' is converted to a number (0) because of the context imposed by the numeric equality operator ==. The LHS value is undef, which is also converted to a number (0), which is why the expression evaluates to true.
The Perl defined function (and many others) returns "a Boolean value".
Given Perl doesn't actually have a Boolean type (and uses values like 1 for true, and 0 or undef for false) does the Perl language specify exactly what is returned for a Boolean values? For example, would defined(undef) return 0 or undef, and is it subject to change?
In almost all cases (i.e. unless there's a reason to do otherwise), Perl returns one of two statically allocated scalars: &PL_sv_yes (for true) and &PL_sv_no (for false). This is them in detail:
>perl -MDevel::Peek -e"Dump 1==1"
SV = PVNV(0x749be4) at 0x3180b8
REFCNT = 2147483644
FLAGS = (PADTMP,IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK)
IV = 1
NV = 1
PV = 0x742dfc "1"\0
CUR = 1
LEN = 12
>perl -MDevel::Peek -e"Dump 1==0"
SV = PVNV(0x7e9bcc) at 0x4980a8
REFCNT = 2147483647
FLAGS = (PADTMP,IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x7e3f0c ""\0
CUR = 0
LEN = 12
yes is a triple var (IOK, NOK and POK). It contains a signed integer (IV) equal to 1, a floating point number (NV) equal to 1, and a string (PV) equal to 1.
no is also a triple var (IOK, NOK and POK). It contains a signed integer (IV) equal to 0, a floating point number (NV) equal to 0, and an empty string (PV). This means it stringifies to the empty string, and it numifies to 0. It is neither equivalent to an empty string
>perl -wE"say 0+(1==0);"
0
>perl -wE"say 0+'';"
Argument "" isn't numeric in addition (+) at -e line 1.
0
nor to 0
>perl -wE"say ''.(1==0);"
>perl -wE"say ''.0;"
0
There's no guarantee that this will always remain the case. And there's no reason to rely on this. If you need specific values, you can use something like
my $formatted = $result ? '1' : '0';
They return a special false value that is "" in string context but 0 in numeric context (without a non-numeric warning). The true value isn't so special, since it's 1 in either context. defined() does not return undef.
(You can create similar values yourself with e.g. Scalar::Util::dualvar(0,"").)
Since that's the official man page I'd say that its exact return value is not specified. If the Perl documentation talks about a Boolean value then then it almost always talks about evaluating said value in a Boolean context: if (defined ...) or print while <> etc. In such contexts several values evaluate to a false: 0, undef, "" (empty strings), even strings equalling "0".
All other values evaluate to true in a Boolean context, including the infamous example "0 but true".
As the documentation is that vague I would not ever rely on defined() returning any specific value for the undefined case. However, you'll always be OK if you simply use defined() in a Boolean context without comparing it to a specific value.
OK: print "yes\n" if defined($var)
Not portable/future proof: print "yes\n" if defined($var) eq '' or something similar
It probably won't ever change, but perl does not specify the exact boolean value that defined(...) returns.
When using Boolean values good code should not depend on the actual value used for true and false.
Example:
# not so great code:
my $bool = 0; #
...
if (some condition) {
$bool = 1;
}
if ($bool == 1) { ... }
# better code:
my $bool; # default value is undef which is false
$bool = some condition;
if ($bool) { ... }
99.9% of the time there is no reason to care about the value used for the boolean.
That said, there are some cases when it is better to use an explicit 0 or 1 instead of the boolean-ness of a value. Example:
sub foo {
my $object = shift;
...
my $bool = $object;
...
return $bool;
}
the intent being that foo() is called with either a reference or undef and should return false if $object is not defined. The problem is that if $object is defined foo() will return the object itself and thus create another reference to the object, and this may interfere with its garbage collection. So here it would be better to use an explicit boolean value here, i.e.:
my $bool = $object ? 1 : 0;
So be careful about using a reference itself to represent its truthiness (i.e. its defined-ness) because of the potential for creating unwanted references to the reference.
I am using LWP::UserAgent like below
my $ua = LWP::UserAgent->new;
my $response = $ua->request ( ...);
if ( $response->is_success() )
{
...
}
print $response->is_success();
Problem I am facing is that is_success() is returning blank. I was expecting 1 (TRUE) or 0 (FALSE). What am I doing wrong here? Is print statement right?
Not returning anything is correct and usual way in Perl to return false result from function, don't expect literal 0 number when you only need logical false result. Your request is most likely returned with non 2xx or 3xx code.
From the Perl documentation:
The number 0, the strings '0' and "" , the empty list () , and undef
are all false in a boolean context. All other values are true.
Negation of a true value by ! or not returns a special false value.
When evaluated as a string it is treated as "" , but as a number, it
is treated as 0. Most Perl operators that return true or false behave
this way.
In other words, your mistake is assuming that boolean false is always represented by 0. It would be more accurate to say that in Perl false is represented by "empty", with what that means depending on the context.
This is useful, because it allows for clean code in a variety of contexts:
#evaluates false when there are no more lines in the file to process
while (<FILE>) { ... }
#evaluates false when there are no array elements
if (!#array) { ... }
#evaluates false if this variable in your code (being used as a reference)
#hasn't been pointed to anything yet.
unless ($my_reference) { ... }
And so on...
In your case, it's not clear why you want false to be equal to zero. The if() statement in your code should work as written. If you need the result to be explicitly numeric for some reason, you could do something like this:
my $numeric_true_false = ($response->is_success() ? 1 : 0);
From the discussion in comments:
$response->status_line
actually returned 500 Can't Connect to database.
With $response->is_success(), I was unable to understand the response from db.
Used $response->status_line to find out exactly where the code was failing.
This Perl code is part of the variable declaration at the beginning of a piece of code. What does it mean?
my $EXPLICIT_YEAR = $ALL_PAGES ? 0 : ($store{year} || $current_year);
It's equivalent to this:
my $EXPLICIT_YEAR;
if ($ALL_PAGES) {
$EXPLICIT_YEAR = 0;
}
else {
# $EXPLICIT_YEAR = $store{year} || $current_year;
if ($store{year}) {
$EXPLICIT_YEAR = $store{year};
}
else {
$EXPLICIT_YEAR = $current_year;
}
}
The $conditional ? $true : $false portion is a ternary if.
The $store{year} || $current_year portion uses the fact that the || operator returns the first value that evaluates to true, allowing $current_year to be used if $store{year} is "false" (zero, empty string, etc.)
my $EXPLICIT_YEAR = $ALL_PAGES ? 0 : ($store{year} || $current_year);
This expression is using the Ternary "?:" operator, combined with a subexpression using the || C-style logical OR. See perldoc perlop.
$ALL_PAGES ?
The expression before the ? - the condition - is evaluated as a boolean expression. A true value meaning any value that is not zero, the empty string or undefined (not declared).
0 : ( $store{year} || $current_year )
The values on either side of : are the values to be returned, depending on the return value of the condition. If the condition evaluates true, return the leftmost value, otherwise the rightmost. The leftmost value is simply zero 0.
$store{year} || $current_year
The rightmost value is an expression itself, using the C-style logical OR operator. It will return the leftmost value, if it evaluates true (and ignore the rightmost). Otherwise it will return the rightmost value. So:
if $ALL_PAGES is true, then set $EXPLICIT_YEAR to zero
else if $ALL_PAGES is false, then:
if $store{year} is true, then set $EXPLICIT_YEAR to $store{year}
else set $EXPLICIT_YEAR to $current_year
I'm not a Perl developer, but I'm 99% sure (this holds in most other languages) that it equates to this: If the variable $ALL_PAGES is true (or 1), then 0 is evaluated, and if not, ($store{year} || $current_year) is evaluated.
i think thats a way of doing a if/then/else
see here: http://www.tutorialspoint.com/perl/perl_conditions.htm
I know 0 perl but a lot of C, so taking a guess here:
Set variable EXPLICIT_YEAR to
( if ALL_PAGES == true then 0
else ( (get store indexed at year) or current_year ))
The or operation is
false or false = false
false or true = true
true or false = true
true or true = true