In perl, $x = if (0) {1} else {2}
does not work.
$ perl -E'$x = if (0) {1} else {2}'
syntax error at -e line 1, near "= if"
Execution of -e aborted due to compilation errors.
This makes sense, because if
conditionals are not expressions in Perl. They're flow control.
But then
my $x = do { if (0) {1} else {2} };
Does work! How come a do BLOCK
can accept an if
conditional? But assignment can not? It would seem in the above the flow control must either
do BLOCK
Moreover given the simple facts above, what is the right way to describe an if-conditional that behaves like that? Is it an expression with a value? Is it flow-control construct that has no value after evaluation?
And, lastly, what modifications would have to be made to assignment to have it accept an if
condition like a do BLOCK
.
The only answer and commentary that addresses the question in a matter that brings clarity is Ginnz,
The over-arching design is that perl has keywords that only are meaningful in certain contexts, and
if
is one of them - it can be only the start of a statement or a statement modifier, and neither of those are valid directly after an=
. This is a parser distinction first and foremost. Beyond that, the consideration of "what anif
statement returns" is not always intuitive, so while you can find that out by putting it in a do block or the last statement of a subroutine, it's not something that should be encouraged to be used as a value. In fact it commonly leads to bugs . – Grinnz 11 hours ago
When Ginnz says parser distinction, I interpret that to mean that this isn't much worth pursing as a matter of clarity. What is valid after an =
is simply not a if
statement, and there is no real reason for it, except that it's how it is.
if
conditional is a statement. =
expressly forbids statements on the right because it only accepts things in the expression class. do BLOCK
can turn a statement into an expression. Code inside DO block behaves differently. Perl interprets the code inside the curly brackets and outputs the result of the last command.
#!/usr/bin/perl
use Data::Dumper;
my $x = do { { 1==1 } };
my $y = do { { 1==0 } };
print Dumper 1==0;
print Dumper $x;
print Dumper $y;
Read more about do: https://perldoc.perl.org/perlfunc#do
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.