What does '//' mean in Perl? [duplicate] - perl

This question already has answers here:
Meaning of // operator in perl
(5 answers)
Closed 9 years ago.
I was searching in a lot of Perl books but I can't find an answer. I have this code, what I suppose it does is assign param's ticket to $ticket iff it exists if not, assign 0.
my $ticket = $params->{ticket} // 0;

// means defined-or. $ticket is assigned $params->{ticket} if it is defined, 0 otherwise.
Although it has no direct equivalent in C, Perl's // operator is related to its C-style or. In fact, it's exactly the same as ||, except that it tests the left hand side's definedness instead of its truth. Thus, EXPR1 // EXPR2 returns the value of EXPR1 if it's defined, otherwise, the value of EXPR2 is returned.
It was added in 5.10.
In the code above, $params->{ticket} can still have garbage in it, so make sure the value conforms to the expected pattern before using it.

Perl documentation says:
"EXPR1 // EXPR2 returns the value of EXPR1 if it's defined, otherwise, the value of EXPR2 is returned."
It's similar to a logic or, but testing definedness.

Related

Difference between & and && in Scala? [duplicate]

This question already has answers here:
Are there good uses for non-short-circuiting logical (boolean) operators in Java/Scala?
(4 answers)
What is the difference between the | and || or operators?
(12 answers)
Why doesn't the bitwise & operator short-circuit?
(5 answers)
Closed 5 years ago.
I am trying to figure out the difference between & and && in Scala. I got this after searching
& <-- verifies both operands
&& <-- stops evaluating if the first operand evaluates to false since the result will be false
Can somebody explain the same with example as am not clear, what verifying both operands means here. Are we talking about just Booleans?
Both are logical AND operators in Scala. The first form, &, will evaluate both operands values, for example:
val first = false
val second = true
if (first & second) println("Hello!")
Will evaluate both first and second before exiting the if condition, although we know that once a false appears in a logical AND, that entire expression will already yield false.
This is what && is for, and what it does is short-circuit the evaluation, meaning you only ever evaluate firsts value and then exit the conditional.
You can use bitwise AND (&) to perform bitwise operations on integers, which is similar to most programming languages.

'If' efficiency when evaluating 2 expressions [duplicate]

This question already has answers here:
Is Perl optimized to skip remaining logic operands if the answer is already decided?
(6 answers)
Closed 7 years ago.
if(expression1 or expression 2)
{
do something
}
If 'expression1' returns true, does the compiler starts to execute 'do something' or it evaluates the second expression too?
No, expression2 will not be evaluated if expression1 is true.
This is because or is short-circutted in perl: once the result of the entire expression is known, evaluation stops. Evaluation occurs from left to right.

Behavior of Scalar::Util::looks_like_number in Perl

I am trying to find out if an input is number or string. I came across looks_like_number and cannot understand the values it returns.
use warnings;
use Scalar::Util qw(looks_like_number);
my $name = 11;
print looks_like_number ($name);
This code prints 1 if $name contains a string and a static number if $name contains an integer (i.e. 4352 for each integer).
I am using Perl on Windows.
You forgot to ask a question! Here are two possibilities.
Why doesn't it always return the same value for true?
Why not? It returns a true value as documented. It makes no difference which true value it is.
What is the value returned?
If the scalar contains a string, it uses grok_number which has specific document return values.
The type of the number is returned (0 if unrecognised), otherwise it is a bit-ORed combination of IS_NUMBER_IN_UV, IS_NUMBER_GREATER_THAN_UV_MAX, IS_NUMBER_NOT_INT, IS_NUMBER_NEG, IS_NUMBER_INFINITY, IS_NUMBER_NAN (defined in perl.h).
Otherwise, it uses
SvFLAGS(sv) & (SVf_NOK|SVp_NOK|SVf_IOK|SVp_IOK)
You can't tell which of the two was used, so you can't ascribe meaning to the value, which is why it's undocumented.
Don't rely on the exact numerical value. This is an abstraction leak, which the latest version of Scalar::Util (1.39) fixes. What is important is simply the truth of the result, not its exact numerical value.
See bug https://rt.cpan.org/Ticket/Display.html?id=94806
This is what the documentation says:
looks_like_number EXPR
Returns true if perl thinks EXPR is a number. See "looks_like_number" in perlapi.
The link to perlapi in this quote is not really helping us a lot unfortunately:
Test if the content of an SV looks like a number (or is a number). Inf
and Infinity are treated as numbers (so will not issue a non-numeric
warning), even if your atof() doesn't grok them. Get-magic is ignored.
I32 looks_like_number(SV *const sv)
In my case, your code will return an integer that is not 0, which is true.
I got 4352 when I used 11.
When I used '11' I got 1.
All of these are true, so that works.
When I put 'test' or 'foobar' I got 0, which is not true.
I never got a 1 for anything that did not look like a number.
I tried '1e1' and it printed 4, which is a true value, and the input looked like a number in scientific notation.
So, I'd say it always returns something true if Perl thinks the input looks like a number, though I do not know what exactly that true value represents. I cannot confirm that it also returns true with a name.

Float comparison issues in Perl [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How do I fix this Perl code so that 1.1 + 2.2 == 3.3?
I'm working on a Perl script that compares strings representing gene models and prints out a summary of the comparison. If the gene models match perfectly, I print out a very terse summary, but if they are different, the summary is quite verbose.
The script looks at the value of a variable to determine whether it should do the terse or verbose summary--if the variable is equal to 1, it should print the terse summary; otherwise, it should print the verbose summary.
Since the value is numeric (a float), I've been using the == operator to do the comparison.
if($stats->{overall_simple_matching_coefficient} == 1)
{
print "Gene structures match perfectly!\n";
}
This worked correctly for all of my tests and even for most of the new cases I am running now, but I found a weird case where the value was equal to 1 but the above comparison failed. I have not been able to figure out why the comparison failed, and stranger yet, when I changed the == operator to the eq operator, it seemed to work fine.
I thought the == was for numerical comparison and eq was for string comparison. Am I missing something here?
Update: If I print out the value right before the comparison...
printf("Test: '%f', '%d', '%s'\n", $stats->{overall_simple_matching_coefficient}, $stats->{overall_simple_matching_coefficient}, $stats->{overall_simple_matching_coefficient});
...I get this.
Test: '1.000000', '0', '1'
The first thing any computer language teacher should teach you about any computer language is that YOU CANNOT COMPARE FLOATS FOR EQUALITY. This is true of any language. Floating point arithmetic is not exact, and two floats that look like they're the same will be different in the insignificant digits somewhere where you can't see it. Instead, you can only compare that they are close to each other - like
if (abs(stats->{overall_simple_matching_coefficient)-1) < 0.0001)
What do you get if you print the value of $stats->{overall_simple_matching_coefficient} just before the comparison? If it's 1, try printf with a format of "%20.10f". I strongly suspect you have some rounding error (less then 1e-6) accumulated in the variable and it's not comparing equal numerically. However when converted to string, since the error is right of the 6th decimal place, and the default string format is to six places, it compares equal.

Why do the '<' and 'lt' operators return different results in Perl?

I am just learning Perl's comparison operators. I tried the below code :-
$foo=291;
$bar=30;
if ($foo < $bar) {
print "$foo is less than $bar (first)\n";
}
if ($foo lt $bar) {
print "$foo is less than $bar (second)\n";
}
The output is 291 is less than 30 (second). Does this mean the lt operator always converts the variables to string and then compare? What is the rationale for Perl making lt operator behave differently from the < operator?
Thanks,
Your guess is right. The alphabetic operators like lt compare the variables as strings whereas the symbolic ones like < compare them as numbers. You can read the perlop man page for more details.
The rationale is that scalars in Perl are not typed, so without you telling it Perl would not know how to compare two variables. If it did guess then it would sometimes getting it wrong, which would lead to having to do things like ' ' + $a < ' ' + $b to force string comparsion which is probably worse than lt.
That said this is a horrible gotcha which probably catches out everyone new to Perl and still catches me out when coming back to Perl after some time using a less post-modern language.
Since Perl is loosely typed, and values can silently convert between strings and integers at any moment, Perl needs two different types of comparison operators to distinguish between integer comparison (<) and string comparison (lt). If you only had one operator, how would you tell the difference?
Rationale? It's a string operator. From "perldoc perlop":
Binary "lt" returns true if the left argument is stringwise less than the right argument.
If that's not what you want, don't use it.
lt compares values lexically (i.e. in ASCII/UNICODE or locale order) and < compares values numerically. Perl has both operators for the same reason "10" + 5 is 15 rather than a type error: it is weakly typed. You must always tell the computer something unambiguous. Languages that are strongly typed tend to use casting to resolve ambiguity, whereas, weakly typed languages tend to use lots of operators. The Python (a strongly typed language) equivalent to "10" + 5 is float("10") + 5.
Does this mean the 'lt' operator
always converts the variables to
string and then compare?
Yes, see perlop
What is the rationale for Perl making
'lt' operator behave differently from
'<' operator?
Because having a numeric comparison operator and a string comparison operator makes a lot more sense then having a mumble mumble operator and another, identical mumble mumble operator.