anagramster has asked for the wisdom of the Perl Monks concerning the following question:
ERROR:
"my" variable $x masks earlier declaration in same scope...
really? when does $x have scope outside the curlys?
or are the two blocks part of the same "virtual" code block?
|
|---|
| Replies are listed 'Best First'. | ||
|---|---|---|
|
Re: strange scope
by Zaxo (Archbishop) on May 22, 2007 at 23:29 UTC | ||
The scope of $x is the entire if . . . else construct. Since the condition following if is always evaluated, that is where the lone my declaration belongs. Consider, but, I agree that that scope is not what one expects. Update: Two more cases, but, showing that $x may be declared in an elsif condition to narrow its scope, if not needed in previous clauses. After Compline, | [reply] [d/l] [select] | |
by blazar (Canon) on May 23, 2007 at 09:12 UTC | ||
I agree that that scope is not what one expects. ISTR that this is a "problem" Perl 6's new scoping rules take care of. | [reply] | |
|
Re: strange scope
by nedals (Deacon) on May 23, 2007 at 00:46 UTC | ||
Looking at it this way, you will notice that both $x's are actually in the same block. Hence the error. So use something like Herkum's solution. | [reply] [d/l] | |
by liverpole (Monsignor) on May 23, 2007 at 01:02 UTC | ||
If you use strict and warnings (or at least warnings), you should get a warning like:
For example, in the following code:
You will get the warning about "= in conditional". It's also interesting to note that this test program, which is essentially equivalent to:
will never terminate, even though $y is set to zero each time, because it's set to 1 immediately before the condition of the while statement is evaluated. s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/ | [reply] [d/l] [select] | |
by jasonk (Parson) on May 23, 2007 at 14:29 UTC | ||
I find it interesting that so many people jumped on the "you don't want to do an assignment in a conditional" bandwagon without even knowing what the right hand side of the assignment is. There are times when an assignment in a conditional is exactly what you want. Here is an example that I use almost daily with DBIx::Class...
The warning you mention only occurs if the right hand side of the assignment is a constant, and the OP didn't include what was in the RHS.
| [reply] [d/l] | |
by Beechbone (Friar) on May 23, 2007 at 15:31 UTC | ||
I also find it strange that a node that completely ignores the question of the op gets such a high reputation. Search, Ask, Know something completly different | [reply] | |
by blazar (Canon) on May 23, 2007 at 09:16 UTC | ||
will never terminate, even though $y is set to zero each time, because it's set to 1 immediately before the condition of the while statement is evaluated. Yep, one would want to use redo there, in that case. | [reply] [d/l] [select] | |
|
Re: strange scope
by naikonta (Curate) on May 23, 2007 at 02:17 UTC | ||
are the two blocks part of the same "virtual" code block?They are in the same scope as Zaxo explains. You can also ask Perl for more help by using diagnostics: would say:
But there's something else. If that's what you really have in your code, you get another warning as liverpole said about Found = in conditional as you can see from the output above. Why? Simple assignment like $x = 'some_value' would always evaluate to true or false (depending the value of 'some_value'). However, if you assign from an expression such as calling a function, then it would be taken as you assign a variable and want to evaluate that variable at once. Consider this: would print 3 without any warnings. I use this construct very often to firstly save a value from a function calling to proceed it further only if it's true. And I keep the variable from visible out of the scope since the variable would be irrelevant for the rest of the code. If you instead, want to test beyond true or false of a variable, you could say for example: but I think it's too much noise. I would instead write something similiar to Herkum's code: So, basically, be clear about what you want to do and what result you expect. Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy! | [reply] [d/l] [select] | |
|
Re: strange scope
by Herkum (Parson) on May 22, 2007 at 23:26 UTC | ||
By doing this, if (my $x = 1)You are testing if the variable assignment works which is the wrong way to approach this problem. Try this,
| [reply] [d/l] [select] | |
by graff (Chancellor) on May 23, 2007 at 01:48 UTC | ||
I don't know if this is the OP's situation, but it would motivate the kind of approach the OP is asking about. There might be other idioms for doing this sort of thing, but doing it this way seems reasonable. | [reply] [d/l] | |
|
Re: strange scope
by anagramster (Novice) on May 23, 2007 at 16:21 UTC | ||
Thanks for all the feedback folks. Zaxo addressed the issue concisely - thanks. For the other posts that ranted about the logic, I am a bit surprised - first, because it's a bit odd to change the logic of some code to fix a warning, and second, it ignores TMTOWTDI (although the trend in paper tomes on Perl seem to be straying from that mantra). Anyways, here's the actual code snippet (parsing S-Expr subset):
And a solution to the warning was never very interesting to me - I had solved it by polluting the enclosing block (as above) and while I liked the single initial def by Zaxo, I chose not to use that because future edits could make the def inadvertently disappear for the 2nd block (a minor annoyance). Onward, McPerl | [reply] [d/l] | |
by naikonta (Curate) on May 25, 2007 at 10:30 UTC | ||
first, because it's a bit odd to change the logic of some code to fix a warningI don't think that logic changing is solely for fixing the warnings. The warnings show up because you ask for it, you ask Perl to warn you if it thinks that you might do something you don't intent. Perl is not always right about this, but mostly is. And there's another way to supress the warning if you're sure about what you're doing without changing the logic. Even if the changing is solely for fixing the warning, I don't see it as odd at all. Most Perlers, at least those around here, don't like the warnings show up, and clutter the error log unintentionally (in the case of web applications). second, it ignores TMTOWTDIHow the logic changing ignores TMTOWTDI? Changing the way something is done is clearly to show another way to do it. And a solution to the warning was never very interesting to meI think I understand your intent in your OP. You think the elsif is in the equal scope as if but Perl doesn't think so hence the warning. But you're interested in knowing why instead of how to get rid of the warnings. The thing is, if you try to understand what the warnings mean, you'll know how to solve the real problem, and get rid of the warnings as well. Hopefully. Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy! | [reply] [d/l] [select] | |