Re^7: Getting an unknown error (foreach $1 breaks m//atch)
by Anonymous Monk on Apr 24, 2015 at 07:29 UTC
|
Wow, what amazing discovery, somebody should perlbug this in a hurry The bug is that it breaks $1 and m//atching operator, and it doesn't warn...
$ perl -wle " $_ = 333; for $1 ( 666 ){ print $1 if /(...)/; }"
666
$ perl -wle " $_ = 333; for $1 ( 666 ){ local our $1; print $1 if /(.
+..)/; }"
Use of uninitialized value $1 in print at -e line 1.
No warnings are issued, matching is broken in a different scope, its a bug ... kind of amazing people don't trip on it every day
Kinda related
Lexical $_ in given/when vs. BLOCK arguments
Bug #115834 for perl5: Successfull match $_[0] =~ /foo(.+)/ overrides $_[0] if function called as foo($1)
| [reply] [d/l] [select] |
|
|
... it breaks $1 and m//atching operator ... No warnings are issued, matching is broken in a different scope ...
It certainly aliases $1 and this is certainly not a good idea, but matching is not broken. (Please see example code below.) A match is made properly and the truth of the match is returned. The content of capture group 1 cannot be directly accessed (because the $1 symbol has been aliased to something else), but the content of this group is still proper and can be accessed indirectly if a kind of "preemptive strike" aliasing of $1 (or rather of the data it symbolizes) has been done. Other variables associated with this group still function as expected. I don't see your point about matching in a different scope (which I take to mean outside the scope of the for-loop alias) being broken; again, see code below. As to warnings... well, as weird as this (ab)use of $1 is, in programmng as in life, it's just not possible to warn about all the weird things one might do; at some point one must fall back upon common sense.
c:\@Work\Perl\monks>perl -wMstrict -le
"for my $one ($1) {
$_ = 'xx333333xx';
for $1 (666) {
print qq{A: '$one' $-[1] $+[1] '$2'} if /(333)\1(xx)/;
print qq{\$1 '$1'};
}
}
;;
print qq{B: '$1' $-[1] $+[1] '$2'} if /(\d\d\d)\1(\D\D)/;
"
A: '333' 2 5 'xx'
$1 '666'
B: '333' 2 5 'xx'
Bottom line: This is just the way aliasing works (insofar as I understand it), but you don't have to use something just because it works. Again, common sense.
Give a man a fish: <%-(-(-(-<
| [reply] [d/l] [select] |
|
|
Using normal variables instead of numbered ones works, too:
for $1 (666) {
if (my ($match) = 333 =~ /(...)/) {
print "$match\t$1\n";
}
}
| [reply] [d/l] |
|
|
...It certainly aliases $1 and this is certainly not a good idea, but matching is not broken. (Please see example code below.) ... This is just the way aliasing works this is just the way something works is the weakest of argument ...
AnomalousMonk , its a bug, warnings doesn't warn
It never occurred to me to try using $1 for anything other than retrieving regex matches
It never even occurred to me to try $1='something' but you can't do that
This is not a feature, its just an oversight
warnings should help the idiot who uses $1 for something other than retrieving regex matches
documentation updates are not any kind of solution
$ perl -le" for my $1 ( 666 ){ print $1 } "
Can't use global $1 in "my" at -e line 1, near "my $1 "
Execution of -e aborted due to compilation errors.
| [reply] [d/l] |
|
|
| [reply] [d/l] [select] |
Re^7: Getting an unknown error
by ww (Archbishop) on Apr 24, 2015 at 11:43 UTC
|
Tracking which node responds to which is getting a little twitchy, so, to be clear, this was written (before the thread got so complicated) in response to Re^6: Getting an unknown error.
----END UPDATE of 2015-04-25----
Excellent discussion, AnomalousMonk, for which, ++.
BUT, it falls short of persuading me: I hew to the notion that docs at the perldoc docname level of authority should accept a (small!) bit of verbosity to handle significant exceptions... or perhaps rephrase to avoid making (what I see as) a manifestly false statement; one which is NOT clarified nor constrained by its context.
In this case, I would argue that it is [ inaccurate | misleading | false ] to state categorically and without qualification (as does perlvar):
These variables are read-only and dynamically-scoped.
I acknowledge a possible reason for believing otherwise than I do... that the context is discussion of the $n variables as used in regexen (under the subhead, "Variables related to regular expressions)."
But, I don't think even that is adequate justification for phrasing that appears to be at the root of an widely-held but inaccurate mime.
Perhaps the doc editors [ could | should ] revise the perlvar statement by adding the word "generally" and extend it by noting that $n can -- BUT SHOULD NOT - be used as an iterator (that may not be sufficiently broad, but I hope it suggests an approach. I find NO caveat on that point in the perldoc .... collection.
Of course, maybe someone will correct me, and find a limiting counterstatement in authoritative documentation; other than the content of this thread) but
| [reply] |
|
|
| [reply] [d/l] |
|
|
I gather that the point in your Re^8: Getting an unknown error (foreach $1 breaks m//atch) is that "it's just not possible to warn about all the weird things one might do; at some point one must fall back upon common sense."
OK; I agree with that, but I've found nothing, nor have you cited anything, that says or suggests it's "weird" to use $n as an iterator. A very succinct clarification is possible: "(I)t's possible, but unwise, to use $n as an iterator."
Think of the frequency with which the perlvar warns "See Performance issues...." or, more generally, that perldocs take the space to observe something on the order of Such-and-such a use of (function) produces undefined results. The cost of this clarification is trivial.
| [reply] [d/l] [select] |