misterperl has asked for the wisdom of the Perl Monks concerning the following question:
that was an hour of my life I won't get back. The code:
use strict;
.
.
next unless s->{ID} =~ /\d\d+/;
.
.
And like 20 lines later, the compiler tells me "Bareword found where operator expected", in the middle of an SQL statement... I'm scrutinizing THAT line, as instructed, and for the life of me, all the quotes and arrows and braces and parens look perfect- I MUST BE MISSING SOMETHING! So I look even harder. And look at nearby lines too. But NOT at 20 lines away!
Now honestly, WHO would think "gee, I better check TWENTY LINES ABOVE this, to find that BAREWORD which isn't allowed in strict..."?? Apparently Larry didn't have his coffee when he wrote THIS check. WTH?? Added the $, program was 100%
Love Perl, it made me 10X more productive than the old J2EE days. But sometimes something like this comes along, and I'm thinking "even after all these years since my first OSCON, Perl STILL ain't ready for primetime"
rant off, back to the code....
Re: Really Perl?
by hippo (Bishop) on Aug 15, 2017 at 15:04 UTC
|
next unless s->{ID} =~ /\d\d+/;
The "s" there is a substitution and your expression as written is unterminated (there are no matching "-"s to indicate the end). If you think perl should tell you that you are missing a $ rather than a - then you are free to suggest a method for determining that, of course.
Me? I'd avoid using variables with the same names as built-in functions where possible. Saves loads of bother.
Addendum: while attempting to reproduce your error, the syntax highlighting in my editor (vim) made it very obvious indeed where the problem lay. It's not for everyone and not necessarily all the time, but syntax highlighting can be a real bonus on occasions such as this.
| [reply] [d/l] |
|
While not disagreeing, I'm as sure as I can be without checking that there are CPAN modules that use "$s" in the synopsis (and later examples) as the example object. It only takes the smallest of mis-clicks when cutting & pasting to get into the position of the OP, for whom I have a great deal of sympathy. I'll see tomorrow if I can find such a culprit & if it's appropriate to try to do anything about it. When I use CPAN modules, I try to stay as close as I can to the synopsis & example code, as it makes appeals for help easier to write.
Regards,
John Davies
Update: finding examples of this is trivial. http://search.cpan.org/~frew/DBIx-Class-DeploymentHandler-0.002219/lib/DBIx/Class/DeploymentHandler.pm is one of many, chosen for no particular reason. I've made a personal resolution to avoid single character names in future, but I have no great ideas as to how to solve this issue generically.
| [reply] |
|
| [reply] |
|
| [reply] |
|
|
|
Sometimes perl will come up with a warning like this
(Might be a runaway multi-line -- string starting on line 42)
when you have a bad q-- somewhere. That's helpful, but it doesn't seem to happen with s---.
| [reply] |
Re: REALLY PERL ??
by Your Mother (Archbishop) on Aug 15, 2017 at 16:17 UTC
|
Perl STILL ain't ready for primetime
That's a bit offputting and plain FUD. Perl has the lowest defect density of any high level language and the best support for many things other languages are generally poor with like Unicode and regex. Perl was "ready for primetime" in 1990 or even earlier and it's only improved since.
When an error seems inscrutable it's usually operator error. I've done it before, spent hours chasing a bad brace once, just as you did here so I'm not harshing on you. It happens. Good practices can keep it a rarity. If the error was obviously not in the indicated line, the first thing to do is start looking backwards or commenting out lines until you get back to the real problem. That would have taken all of 3 minutes. As hippo said, better variable/sub names are a help, single letter names are code smell. Twenty+ lines of bare code is fine; keeping things in tight blocks and subs makes problems harder to introduce and easier to find.
| [reply] |
|
keeping things in tight blocks and subs makes problems harder to introduce and easier to find.
That, right there.
Sometimes, depending on the issue, Perl will inform you of a problem on a line that doesn't seem correct, because it can't accurately figure out exactly what line it really happened on. Parsing Perl is most definitely not a trivial task, and sometimes even the interpreter can't quite figure it out when dealing with syntax issues. Keeping your blocks/subs etc so they fit within a single screen (where feasible/possible) significantly aids in finding these issues.
Throw in a decent IDE or even editor (vi/vim was thrown around) can help with this process as they can highlight the specific issue.
As far as the OP's comment about "prime-time", that's asinine. Other programming languages throw the same way Perl does in this regard in certain situations, unable to identify the exact line number. Heck, I can even get C to do this, so I won't go any further into that FUD, as Your Mother aptly put it. I'll just chalk that up as being claimed out of pure frustration by OP.
| [reply] |
|
| [reply] |
|
| [reply] |
|
Re: REALLY PERL ??
by shmem (Chancellor) on Aug 15, 2017 at 15:11 UTC
|
In some situations, the compiler has a really hard time to get what's wrong in the first place.
qwurx [shmem] ~> perl -Mstrict -E 's->{ID}'
Substitution pattern not terminated at -e line 1.
Surely the compiler was looking for more dashes to appear in the source to complete s/// (written as s---), which happened many more lines down. Then something else went wrong, probably - hard to tell without seeing the complete code.
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
| [reply] [d/l] |
Re: REALLY PERL ??
by Marshall (Canon) on Aug 15, 2017 at 19:52 UTC
|
One technique I sometimes use to comment out a bunch of Perl lines is to put in some temporary POD directives. =Any header..lines...=cut Start the "=" in column 1. Perl figures that the included lines are "Plain Old Documentation" and Perl doesn't compile them. C has a multi-line comment syntax. Perl doesn't, but this is a good substitute.
I also recommend just moving an __END__ statement around in the code.
Everybody here has had some kind of syntax problem that at one time stumped them for awhile. This is a normal part of software development. I would argue to anybody who claims that has never happened: a) you are lying or b) you don't have enough experience.
I think just last week, I had a really bizarre looking error that I traced back to a ":" instead of a ";" at the end of a "use" statement. It didn't take long for me to figure out the problem. But yes, an error 20 lines later can and does happen. I've seen that in every HLL that I've used. | [reply] [d/l] [select] |
|
G'day Marshall,
++
They're all good techniques which I use too.
I also sometimes add a temporary exit statement: often in a loop to see print debug statements
for just one iteration.
I almost always add something like
# TODO - debugging
just before those things so that they're easy to subsequently find and remove.
My normal syntax highlighting displays the commented "TODO" in a horribly contrasting magenta on blue
so it's really hard to miss; even without that, it's easy to just search the text for.
"... a really bizarre looking error that I traced back to a ":" instead of a ";" at the end ..."
Unfortunately, that's one mistake I make far too often.
It was very difficult to track down when I first used to make it.
I now recognise it as just something I do when not releasing the Shift key quickly enough:
$result = function(...):
$hashref = { ... }:
$string = "...":
It's easy to miss when just reviewing the code because ":" and ";" look very similar;
at least now it's easy to find and fix when I get a syntax error reported.
| [reply] [d/l] [select] |
Re: REALLY PERL ?? splain/diagnostics?
by Anonymous Monk on Aug 15, 2017 at 18:41 UTC
|
#!/usr/bin/perl --
use strict;
next unless s->{ID} =~ /\d\d+/;
print 1;
print "a - b -Q";
$ perl5.8.9.exe reallyperlconfusingerror.pl
Bareword found where operator expected at reallyperlconfusingerror.pl
+line 5, near "print "a - b -Q"
(Might be a runaway multi-line -- string starting on line 3)
(Do you need to predeclare print?)
String found where operator expected at reallyperlconfusingerror.pl li
+ne 5, at end of line
(Missing semicolon on previous line?)
syntax error at reallyperlconfusingerror.pl line 5, near "print "a - b
+ -Q"
Can't find string terminator '"' anywhere before EOF at reallyperlconf
+usingerror.pl line 5.
$ perl5.16.1.exe reallyperlconfusingerror.pl
Having no space between pattern and following word is deprecated at re
+allyperlconfusingerror.pl line 5.
Bareword found where operator expected at reallyperlconfusingerror.pl
+line 5, near "print "a - b -Q"
(Might be a runaway multi-line -- string starting on line 3)
(Do you need to predeclare print?)
String found where operator expected at reallyperlconfusingerror.pl li
+ne 5, at end of line
(Missing semicolon on previous line?)
syntax error at reallyperlconfusingerror.pl line 5, near "print "a - b
+ -Q"
Can't find string terminator '"' anywhere before EOF at reallyperlconf
+usingerror.pl line 5.
$ perl5.16.1.exe -Mdiagnostics reallyperlconfusingerror.pl
Having no space between pattern and following word is deprecated at
reallyperlconfusingerror.pl line 5 (#1)
(D syntax)
You had a word that isn't a regex modifier immediately following
a pattern without an intervening space. If you are trying to use
the /le flags on a substitution, use /el instead. Otherwise, add
white space between the pattern and following word to eliminate
the warning. As an example of the latter, the two constructs:
$a =~ m/$foo/sand $bar
$a =~ m/$foo/s and $bar
both currently mean the same thing, but it is planned to disallow
the first form in Perl 5.18. And,
$a =~ m/$foo/and $bar
will be disallowed too.
Bareword found where operator expected at reallyperlconfusingerror.pl
+line 5, near "print "a - b -Q"
(Might be a runaway multi-line -- string starting on line 3) (#2)
(S syntax) The Perl lexer knows whether to expect a term or an ope
+rator.
If it sees what it knows to be a term when it was expecting to see
+ an
operator, it gives you this warning. Usually it indicates that an
operator or delimiter was omitted, such as a semicolon.
(Do you need to predeclare print?)
String found where operator expected at reallyperlconfusingerror.pl li
+ne 5, at
end of line (#2)
(Missing semicolon on previous line?)
syntax error at reallyperlconfusingerror.pl line 5, near "print "a - b
+ -Q"
Can't find string terminator '"' anywhere before EOF at reallyperlconf
+usingerror.pl line 5 (#3)
(F) Probably means you had a syntax error. Common reasons include
+:
A keyword is misspelled.
A semicolon is missing.
A comma is missing.
An opening or closing parenthesis is missing.
An opening or closing brace is missing.
A closing quote is missing.
Often there will be another error message associated with the synt
+ax
error giving more information. (Sometimes it helps to turn on -w.
+)
The error message itself often tells you where it was in the line
+when
it decided to give up. Sometimes the actual error is several toke
+ns
before this, because Perl is good at understanding random input.
Occasionally the line number may be misleading, and once in a blue
+ moon
the only way to figure out what's triggering the error is to call
perl -c repeatedly, chopping away half the program each time to se
+e
if the error went away. Sort of the cybernetic version of 20 ques
+tions.
Uncaught exception from user code:
syntax error at reallyperlconfusingerror.pl line 5, near "prin
+t "a - b -Q"
Can't find string terminator '"' anywhere before EOF at really
+perlconfusingerror.pl line 5.
| [reply] [d/l] [select] |
Re: REALLY PERL ??
by will_ (Scribe) on Mar 16, 2018 at 12:40 UTC
|
...and that's why we give our variables meaningful names, instead of single character names like $s
perl easy_fix.pl
#!/usr/bin/perl --
use strict;
next unless meaningful_name->{ID} =~ /\d\d+/;
print 1;
print "a - b -Q";
Output:
Can't use bareword ("meaningful_name") as a HASH ref while "strict refs" in use at easy_fix.pl line 3.
(Perl v5.18.2)
| [reply] [d/l] |
|
|