I am new to perl. Can anyone please explain the meaning of // operator in perl.
It's the definedness operator. The expression:
A // B
will return A if it's defined, otherwise B.
It's very useful for getting default values if the source of the information is not defined, with things like:
$actualBalance = $balanceFromBank // 0;
or:
$confirmation = $userInput // "N";
See the relevant part of the perlop page for more detail and make a link of perlop for future reference, since Google searches and the punctuational Perl code don't mix that well :-)
The // operator is a logical defined-or. Perlop says:
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. (EXPR1 is
evaluated in scalar context, EXPR2 in the context of // itself).
Usually, this is the same result as defined(EXPR1) ? EXPR1 : EXPR2
(except that the ternary-operator form can be used as a lvalue, while
EXPR1 // EXPR2 cannot). This is very useful for providing default
values for variables. If you actually want to test if at least one of
$a and $b is defined, use defined($a // $b) .
In short: It returns the left side if that expression is defined (as in not undef), or the right side.
my $foo = undef;
say $foo // 42;
# 42
my $bar = 'bar';
say $bar // 42;
# bar
It's so called defined-or operator, which has been implemented in Perl 5.10. Example from the doc:
The following expression:
$a // $b
... is merely equivalent to
defined $a ? $a : $b
And the statement:
$c //= $d;
... can now be used instead of
$c = $d unless defined $c;
Here's how || and // are different:
use 5.010;
my $rabbits = 0;
say $rabbits || 1; # 1, as 0 || 1 evaluates to 1
say $rabbits // 1; # 0, as 0 is not `undef`
That is "defined-or". $abc // "default" is equivalent to defined($abc) ? $abc : "default". Meaning if the left side of // has a defined value then that value is used, otherwise the right side of it.
See "Logical defined-or" in the perlop man page.
is defined or
like,
my $a //= 3;
will assign 3 to $a
it is different from ||, which is simply, or in that:
my $a = "";
$a //= 3;
print "|$a|\n";
$a = "";
$a ||=5;
print "|$a|\n";
will print only |5|, because in the first case $a is defined (with a false value), while in the second it matters if $a evaluates to true or not.
Related
please see the below code:
$scalar = 10;
subroutine(\$scalar);
sub subroutine {
my $subroutine_scalar = ${$_[0]}; #note you need the {} brackets, or this doesn't work!
print "$subroutine_scalar\n";
}
In the code above you can see the comment written "note you need the {} brackets, or this doesn't work!" . Please explain the reason that why we cant use the same statement as:
my $subroutine_scalar = $$_[0];
i.e. without using the curly brackets.
Many people have already given correct answers here. I wanted to add an example I found illuminating. You can read the documentation in perldoc perlref for more information.
Your problem is one of ambiguity, you have two operations $$ and [0] working on the same identifier _, and the result depends on which operation is performed first. We can make it less ambiguous by using the support curly braces ${ ... }. $$_[0] could (for a human anyway) possibly mean:
${$$_}[0] -- dereference the scalar $_, then take its first element.
${$_[0]} -- take element 0 of the array #_ and dereference it.
As you can see, these two cases refer to completely different variables, #_ and $_.
Of course, for Perl it is not ambiguous, we simply get the first option, since dereferencing is performed before key lookup. We need the support curly braces to override this dereferencing, and that is why your example does not "work" without support braces.
You might consider a slightly less confusing functionality for your subroutine. Instead of trying to do two things at once (get the argument and dereference it), you can do it in two stages:
sub foo {
my $n = shift;
print $$n;
}
Here, we take the first argument off #_ with shift, and then dereference it. Clean and simple.
Most often, you will not be using references to scalar variables, however. And in those cases, you can make use of the arrow operator ->
my #array = (1,2,3);
foo(\#array);
sub foo {
my $aref = shift;
print $aref->[0];
}
I find using the arrow operator to be preferable to the $$ syntax.
${ $x }[0] grabs the value of element 0 in the array referenced by $x.
${ $x[0] } grabs the value of scalar referenced by the element 0 of the array #x.
>perl -E"$x=['def']; #x=\'abc'; say ${ $x }[0];"
def
>perl -E"$x=['def']; #x=\'abc'; say ${ $x[0] };"
abc
$$x[0] is short for ${ $x }[0].
>perl -E"$x=['def']; #x=\'abc'; say $$x[0];"
def
my $subroutine_scalar = $$_[0];
is same as
my $subroutine_scalar = $_->[0]; # $_ is array reference
On the other hand,
my $subroutine_scalar = ${$_[0]};
dereferences scalar ref for first element of #_ array, and can be written as
my ($sref) = #_;
my $subroutine_scalar = ${$sref}; # or $$sref for short
Because $$_[0] means ${$_}[0].
Consider these two pieces of code which both print 10:
sub subroutine1 {
my $scalar = 10;
my $ref_scalar = \$scalar;
my #array = ($ref_scalar);
my $subroutine_scalar = ${$array[0]};
print "$subroutine_scalar\n";
}
sub subroutine2 {
my #array = (10);
my $ref_array = \#array;
my $subroutine_scalar = $$ref_array[0];
print "$subroutine_scalar\n";
}
In subroutine1, #array is an array containing the reference of $scalar. So the first step is to get the first element by $array[0], and then deference it.
While in subroutine2, #array is an array containing an scalar 10, and $ref_array is its reference. So the first step is to get the array by $ref_array, and then index the array.
I am new to Perl. I am still trying to learn the syntax of it. I have seen someone using // and //= in Perl but I couldn't find any resources on the web that explain this.
Can someone explain to me what exactly does it mean in layman terms? And what it actually does?
As kjprice mentioned, // is the logical 'defined or' operator and is documented here on the perlop page and the relevant excerpt is
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.
You can think of
my $var = EXPR1 // EXPR2;
as a short hand way of writing:
my $var;
if ( defined EXPR1 ) {
$var = EXPR1;
} else {
$var = EXPR2;
}
I often use this to either assign a default value to a variable unless a supplied by command line or config file value is supplied. Something like:
my $var = $config_version // 'foo';
The //= is a variation of this with an assignemnt mixed in. That same perlop page says this:
Modifying an assignment is equivalent to doing the assignment and then
modifying the variable that was assigned to.
For //= that means instead of writing something like
my $var = EXPR1 // EXPR2;
You could write
my $var = EXPR1;
$var //= EXPR2;
and get equivalent values.
From the perldoc perlop:
Logical Defined-Or
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. (EXPR1 is evaluated in scalar context, EXPR2 in the context of // itself). Usually, this is the same result as defined(EXPR1) ? EXPR1 : EXPR2 (except that the ternary-operator form can be used as a lvalue, while EXPR1 // EXPR2cannot). This is very useful for providing default values for variables. If you actually want to test if at least one of $a and $b is defined, use defined($a // $b).
So:
$NODEFINED // $DEFINED # will return the value of defined
$DEFINED1 // $DEFINED2 # will return the value of $DEFINED1
$a //= $b;
is shorthand for:
$a = $a // $b;
So $a will be set to the value $b ONLY if $a is undefined.
The $a //= 42; form is useful for setting a default for a variable that may not yet be defined.
Could someone help me to understand what the '+=' operator means in a particular situation. The script says:
$receipts{$weather} += $receipt;
$days{$weather}++;
Assuming $foo += $bar, the += operator does the following:
$foo = $foo + $bar;
That is, increments $foo by $bar. Assuming $foo++, the ++ operator does the following:
$foo = $foo + 1;
That is, increments the variable by one.
With all this said, these operators also have some hidden perl magic. For example, the += and ++ operator does not give an uninitialized warning where the corresponding statement would:
# $foo is undefined
$foo += 10; # no warning
$foo++; # no warning
$foo = $foo + 10 # Use of uninitialized value $foo in addition
The ++ operator also works on strings
my $foo = 'a';
$foo++;
print $foo; # prints 'b'
The ++ operator comes in two flavours, post increment and pre increment. The return value of the expression is either calculated before or after the incrementation:
$foo = 1;
print ++$foo; # prints 2
print $foo++; # prints 2, but $foo is now 3
It is adding the value of $receipt to the value of $receipts{$weather} and storing the result back into $receipts{$weather}. It is the equivalent of:
$receipts{$weather} = $receipts{$weather} + $receipt
However, it may be implemented more efficiently in some cases.
See perldoc perlop:
"=" is the ordinary assignment operator.
Assignment operators work as in C. That is,
$a += 2;
is equivalent to
$a = $a + 2;
Example:
this example : int i = 2; i=i+4; and this example int i = 2; i+=4 are the same;
During the process of testing my Perl code using "Smart Match(~~)" I have faced this problem. Will there be any difference between 42, 42.0, "42.0", "42"
$var1 = "42";
$var2 = "42.0";
$a = $var1 ~~ $var2;
I am getting $a as 0; which means $var1 and $var2 are not equal.
Please Explain.
The smart match operator will "usually do what you want". Please read this as "not always".
42 ~~ 42.0 returns true.
42 ~~ "42.0" returns true as well: the string is compared to a number, and therefore seen as a number. Ditto for "42" ~~ 42.0.
"42" ~~ "42.0" returns false: both arguments are strings, and these strings do not compare as "equal", although their numerical meaning would. You wouldn't want Perl to view "two" ~~ "two-point-oh" as true.
A string can be forced to it's numeric interpretation by adding zero:
0+"42" ~~ "42.0" returns true again, as the first string is forced to the number 42, and the second follows suit.
The perldoc perlsyn or perldoc perlop page defines how smart matching works:
Object Any invokes ~~ overloading on $object, or falls back:
Any Num numeric equality $a == $b
Num numish[4] numeric equality $a == $b
undef Any undefined !defined($b)
Any Any string equality $a eq $b
You can see that string equality is the default.
You may want to reconsider using smart match for now. The current implementation is considered by the Perl community to be a mistake, among others because of your question and amon's answer.
Work is ongoing for a "saner" and simpler, but incompatible version of smart match which might be in the next major release of Perl (5.18). It will simply outlaw your example: $a ~~ $b will not be allowed when $b is a simple scalar value (like 42 or "42").
If you have too much time on your hand, you could peruse the Perl5 porters archives, for instance this thread.
Contextual typing.
$Var1 and $Var2 were last used as strings (in the assignment) so now they behave as strings. ~~ will do string comparison if both arguments are strings.
If you use one of them as a number - you don't even need to assign to it - then it will behave as a number and ~~ will use a numeric comparison.
This script will output NO YES:
my $v1 = "42";
my $v2 = "42.0";
print (($v1 ~~ $v2) ? 'YES ' : 'NO ');
$v1 + 0;
print (($v1 ~~ $v2) ? 'YES ' : 'NO ');
Reference for ~~ operator
Why does // have lower precedence than == in (at least) perl 5.010?
For example, this
use 5.010;
my $may_be_undefined = 1;
my $is_equal_to_two = ($may_be_undefined//0 == 2);
say $is_equal_to_two;
prints (for me) very unexpected result.
It's because of the category of operators which // falls under, aswell as ==.
== is an "equality operator" though // falls under the category of "C-style logical operators".
As an example; && is in the same "category" as //, with that said both of the statements below are equivalent when it comes to operator precedence. That might make it easier to understand?
print "hello world" if $may_be_undefined && 0 == 2;
print "hello world" if $may_be_undefined // 0 == 2;
Documentation of C-style Logical Defined-Or ( // )
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, $a // $b is similar to defined($a) || $b (except that it returns the value of $a rather than the value of defined($a)) and yields the same result as defined($a) ? $a : $b (except that the ternary-operator form can be used as a lvalue, while $a // $b cannot).
This is very useful for providing default values for variables. If you actually want to test if at least one of $a and $b is defined, use defined($a // $b) .
The ||, // and && operators return the last value evaluated (unlike C's || and &&, which return 0 or 1).
Documentation of Operator Precedence and Associativity