Re^4: Control Structures
by dragonchild (Archbishop) on May 10, 2005 at 15:23 UTC
|
I disagree - that's not a problem with the trailing if(). That's a problem with how my() is implemented as both a compile-time and run-time actor. The trailing if() is doing exactly what it's supposed to do, which is execute the statement at run-time if the conditional is true.
The reason it's counter-intuitive is because my() is the only statement that affects the current scope with both compile-time and run-time actions. If you use a standard if-block with {}, you create a new scope and everything acts as expected.
- In general, if you think something isn't in Perl, try it out, because it usually is. :-)
- "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"
| [reply] |
|
|
Try explaining that to a mid-level perl developer or an experienced programmer who is still learning perl and watch their eyes glaze over. The problem goes away if you don't use trailing if() statements.
| [reply] |
|
|
| [reply] |
|
|
The problem goes away if you don't use trailing if() statements modifying my() statements. The trailing if() isn't the problem; the problem is when it's modifying a my() statement. Disallow that. Later, when they're ready, they'll ask why that specific prohibition and you'll explain it to them and they'll understand. In fact, you can almost consider that a rite of passage from journeyman to master.
- In general, if you think something isn't in Perl, try it out, because it usually is. :-)
- "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"
| [reply] |
|
|
|
|
|
|
Re^4: Control Structures
by demerphq (Chancellor) on May 10, 2005 at 15:33 UTC
|
Ah, that error. Well i thought 5.8.x was supposed to warn when this happened but based on the tests I just did it doesnt. Maybe its 5.10 when its supposed to happen. But I do agree with dragonchild that its a bit hard on if() to consider it a bug when in fact the error is in the my(). :-)
Anyway, it is a good thing to keep in mind. If you want to do conditional initialization as part of the declaration of a lexical you should always use the ternary operator and not a modifier. I guess I have this lesson so hammered into my head that I find it hard to see it as an error, which of course it is.
---
$world=~s/war/peace/g
| [reply] |
Re^4: Control Structures
by glwtta (Hermit) on May 12, 2005 at 03:16 UTC
|
Seems like a classic case of "doctor, it hurts when I do this".I'd consider myself a mid-level Perl programmer, it's never even occured to me to try my $foo if $bar, simply because "conditional declaration" isn't a concept that makes sense to me. I understand the linked explanation, I'm just saying I would never have arrived at that construct on my own, so it seems unlikely to cause trouble for new programmers. If people feel the need to abuse the side effects of an implementation bug in production code, well, that's not a problem with the language design. | [reply] [d/l] |
|
|
If you think it's that obvious, you're not getting it. Here's some code that demonstrates how this can bite you:
sub sticky {
my $arg = shift;
my $object = Some::Package->new() if $arg;
$object ||= Other::Package->new();
}
The first time you run it with $arg = 0, you will get the expected
result. The second time through with $arg = 0, you will find the
Other::Package object from last time in $object and it will not get a
fresh Other::Package object assigned to it. So, if you never put
anything in $object when the conditional is false, you won't actually
see the bug.
I have personally seen people lose days debugging problems caused by this, and have heard stories about it happening in other companies too. It's hard to see, it's very hard for people to fully understand, and it really happens in production code. | [reply] [d/l] |
|
|
sub foo {
my $arg = shift;
my $object = ($arg) ? Some::Package->new() : Other::Package->new();
}
It seems blindingly obvious that the snippet you provided is not the way to go about it. I agree that the compiler should warn you about this (or better yet, disallow it entirely); it just seems that if someone has trouble with this, the problem probably lies with understanding 'my', not confusing if() syntax. | [reply] [d/l] |
|
|