my $code = "work" unless Run::Env->mod_perl and time % 2;

jozef on 2009-05-16T13:28:40

So time ago 迪拉斯 told me I should not use my together with a condition. He told me it's undefined behaviour, if the contrition is not met and asked me what am I expecting to have in the variable if the condition is not met. I was expecting undef and it actually worked like that. I was not too much excited and just told my self "let's just don't do it from now on".

Days passed and one day we got a strange behaviour in our mod_perl application. A variable was set even it was not supposed to be. The reason was simple. The condition was not met, but instead of undef the variable had the value from a previous request... Was funny in our case but in others it could lead to security problem.

Lesson learned - next time pay more attention to what my colleagues are telling and never use my+if :-)


perlcritic

chorny on 2009-05-16T16:25:47

Perl::Critic warns against this, try checking your code with it.

A better way

jtrammell on 2009-05-16T17:48:28

I find this sort of code to be less problematic:

my $foo = test() ? 'bar' : undef;

Persistem my variables?

potyl on 2009-05-17T07:48:37

If I get it right the faulty statement was something like: my $var = 'passed' if cond();, right? This looks really strange and funny to me. I understand it as execute this statement (which declares a variable) only if the condition is true. If the condition is false then the statement shouldn't be executed, thus no creation of variable. That's not what Perl might do as I'm expecting Jozef to be using "strict" and his module might have not compiled otherwise avoiding this peculiar situation. You where using strict right?

What I don't understand is how the variable could have been reset to it's previous value? Unless if the variable was a global variable this shouldn't happen. Perl is supposed to destroy all lexical variables after the end of the block. How can Perl manage to preserve the value?

Re:Persistem my variables?

Aristotle on 2009-05-18T03:47:47

It generally keeps the “pad” (the allocation space for lexicals, basically) around. Sometimes, eg. for recursive calls, it will allocate extra pads that may be garbage-collected later. So this faux-feature actually doesn’t work reliably except in the simplest use cases. It’s a good thing that 5.10 deprecates it and 5.12 will probably throw an error for such usages.

Re:Persistem my variables?

daxim on 2009-05-18T10:47:30

thread on p5p http://markmail.org/thread/yfxkc6sbw2ydvcjz

Maybe this is what you all are missing.

pozer on 2009-05-17T10:32:58

my $stuff = test() || '' if $some_thing;

Re:Maybe this is what you all are missing.

Aristotle on 2009-05-18T03:48:21

That does not work any better.