What is this line of code trying to do? - perl

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

Related

Why is `!!(a||!a)` always true?

I'm a Java rookie and in School we got some homework. I shall explain boolean terms but I don't understand one of them.
The question is
Why is this expression always true?
!!(a||!a)
I understand the part in the brackets but what do the two exclamation marks in front of it?
If the first a = true --> !a = not true --> !! ( double negation = true?) a = true and the second !a = not true --> !!a = true --> !!!a = not true
and if I'm right , why is this expression alsways true? That beats me.
Could any of you explain that to me?
Thanks for your help!
First off, !! expression cancels out: it’s the same as expression, because the negation of a negation is the original value.
So we’re left with a || ! a, which is a disjunction. So the result is true if at least one of the sub-expressions a or !a is true.
And lastly, a is true if a is true (duh). And ! a is true if a is false. Thus, regardless of the value of a, the overall expression is true.
If "a" is TRUE add "!a" is FALSE
Knowing a is true and !a is false (! is for the negation; in this case, negating true -> false)
If a||!a means true or false, and from that expression you get true...
You can see it like this:
!!(true).
What is the result of a double negation? True.
Then, true(true) = (aka a||!a), which finally makes your expression !!(a||!a) always true.
If "a" is FALSE and "!a" is TRUE
Knowing a is false and !a is true (! is for the negation; in this case, negating false -> true)
If a||!a means false or true, and from that expression you get true...
You can see it like this:
!!(true).
What is the result of a double negation? True.
Then, true(true) = (aka a||!a), which finally makes your expression !!(a||!a) always true.
!!(a||!a)
Using one of the axioms of Boolean Algebra, a double negation cancels out everything.
so it would be equivalent to say (a||!a).
Assuming, we set a = true; many programing languages use lazy evaluation of conditional statements, the conditional statement would evaluate to true and execute whatever was inside the body of the if statement.
If we set a = false , then the right hand side of the conditional statement becomes true... as !a is the inverse of a meaning if a == false, !a == true.

IntValue ?? 0 == -1? "-": "+" What does this mean?

I am importing price information and adding + or -.
I put the title code in print () and it works but I do not know what it means.
print("\(IntValue ?? 0 == -1 ? "-" : "+")")
Please explain it briefly to me.
Kevin's answer is very good.
Some background that helps explain further:
The code you posted uses two rather cryptic operators together.
?? is the nil-coalescing operator.
It takes an optional value, which can contain nil, and provides a new value to use when it does contain nil.
Edit:
(Note that you can skip the nil-coalescing operator and use IntValue == -1 instead. That works because only a non-nil value of -1 is equal to -1. An optional that contains nil is not equal to -1.
You could rewrite the line as
print("\(IntValue == -1 ? "-" : "+")")
And get the same result.)
The next tricky bit is the "ternary operator". This comes from C. It's quite cryptic, but also quite useful.
It takes the form boolean ? value_for_true : value_for_false
Where boolean is a boolean expression that evaluates to true or false.
If boolean is true, then the result of the whole ternary expression is the value_for_true sub-expression.
If boolean is false the result of the whole ternary expression is the value_for_false sub-expression.
IntValue ?? 0 == -1 is the boolean part of your ternary expression. It evaluates as true if IntValue is -1. It evaluates as false if IntValue contains any other value, or if it contains nil.
(Note that variables and let constants should start with lower-case letters, so IntValue should be intValue.)
The variable IntValue is an optional, which means its either an Integer or nil. IntValue ?? 0 means that if IntValue exists, then use the value of IntValue. If IntValue is nil, then use the value 0. Next, compare that value with -1. If that value is equal to -1, then print -. If that value does not equal -1, then print +.
Here's equivalent code with only if statements:
var defaultInt = 0
if IntValue != nil {
defaultInt = IntValue! // force unwrap the optional value
}
if defaultInt == -1 {
print("-")
}
else {
print("+")
}

C# Bool operand usage

I want to have the following results
A B =
T T T
F T F
T F F
F F F
I am using this clause to achieve it
A || B
but it does not provide correct results.
Am I using a wrong operand?
Allthough all other answers are correct, I'd like to point out that the operator you are asking for is neither || nor &&. The operator that actually does exactly what you are asking for is & (and the equivalent that you are mistakenly using would be |).
And, what is the difference? || and && are short circuiting operators. What does that mean? It means that whatever is on the right side of the operator is only evaluated if the left hand side is true. This does not happen with the non short circuit versions of the operators (the truly bolean logical and and or operators):
public bool True()
{
Console.WriteLine("True called.");
return true;
}
public bool False()
{
Console.WriteLine("False called.");
return false;
}
var b1 = False() && True(); //b1 will be false and "False called." will be
//printed on the console.
var b2 = False() & True(); //b2 will be false and "False called. True called."
//will be printed on the console.
You want an and, but you used an or.
Am I using a wrong operand?
Yes you are.
You need the AND && operator which will be true only if all of the conditions are true.
You are using the OR || operator which will give you true even if one of the conditions are true.
Use the AND && operator instead of OR ||
Use && (which means 'and')
|| means 'or'

What this mean !$var PERL?

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

What do Perl functions that return Boolean actually return

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.