Re: How do I find the missing curly brace??
by GrandFather (Saint) on Dec 30, 2024 at 22:14 UTC
|
Looking at some of the code you have published on PerlMonks I notice that your indentation and coding style can be a bit mixed. Using consistent indentation and coding style makes it harder to mismatch paired constructs and makes it easier to find errors when you do manage to get it wrong.
Decent editors allow you to jump between matching parentheses, brackets and so on. With consistent indentation you can work through blocks in your code jumping between brackets until you find an indentation mismatch.
Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
| [reply] |
|
^ That. All of it.
A decent editor/IDE will help track these types of issues down quickly, but a consistent coding style and layout will help prevent the developer from causing these issues in the first place, while providing simpler at-a-glance discrepancy finds even if a decent editor isn't available if a mistake is made.
| [reply] |
Re: How do I find the missing curly brace??
by 1nickt (Canon) on Dec 30, 2024 at 16:39 UTC
|
Use version control. Then it won't matter if you forget where you made the changes.
The way forward always starts with a minimal test.
| [reply] |
|
| [reply] |
|
| [reply] |
Re: How do I find the missing curly brace??
by karlgoethebier (Abbot) on Dec 30, 2024 at 17:45 UTC
|
| [reply] |
Re: How do I find the missing curly brace??
by LanX (Saint) on Dec 30, 2024 at 20:57 UTC
|
maybe the fastest possibility to find such a bug without knowing the last healthy state:
- use perltidy to indent the whole file, should generate a separate .tdy file by default
- grep all occurrences of "{" and "}" into a separate file
- go to the end of file and scroll back till the indentation looks normal
I tried this with a 30k lines module and the output had 5k lines.
you'll get something like this which is easier to be checked visually:
One extra hint: since nesting subs is rare in Perl I'd also grep for sub keywords which are (unusually) intended.
That's only 600 lines in this case.
Apply perltidy -csci=0 -csc for "closing side comments" everywhere to identify the closing } of sub, if, etc.
| [reply] [d/l] [select] |
|
perltidy is a good suggestion. Similarly, vim or some other editor that does highlighting or highlights the start/end of the current BLOCK, might be useful. I wonder if perlcritic would similarly be useful? And maybe as a final stab, perl -c.
| [reply] [d/l] [select] |
|
perl -c will just reproduce the same error he already reported.
But probably he can do a binary search by only compiling the first half of the source.
If it works add a quarter, otherwise subtract one.
And so on, till he identified the problem...
I think he will need to do the splitting manually tho, and can't rely on an automatic bisect.
| [reply] [d/l] |
|
|
| [reply] |
Re: How do I find the missing curly brace??
by Paladin (Vicar) on Dec 30, 2024 at 18:15 UTC
|
Everyone has given lots of great advice so far, but to show you why this is a non-trival problem conciser the following code with a missing }.
if ($foo) {
print "A\n";
print "B\n";
print "C\n";
Where is the missing } ? There's many places it could go and be a valid program. Only you, the programmer, knows which is the correct location. | [reply] [d/l] |
Re: How do I find the missing curly brace??
by NERDVANA (Priest) on Dec 31, 2024 at 01:56 UTC
|
In a project I maintain with 170K lines of perl (excluding generated code), the longest file is 4500 lines and the second-longest is 2884 lines.
I know this probably seems like an unhelpful suggestion for your current situation, but you should consider being nice to yourself and divide your project into smaller modules.
| [reply] |
|
many things that look complicated at first (using strict, subroutines, modules, options, POD, version control, etc.), can and in fact do alleviate things (and perhaps life in general)
| [reply] |
Re: How do I find the missing curly brace??
by stevieb (Canon) on Dec 31, 2024 at 09:39 UTC
|
Have you ever had a perl script that is like 20000 lines long
Yes, inherited.
Learn VCS. Learn to commit small pieces with detailed but concise messages. Then break that up into multiple functional subroutines. Each sub should do only one thing (if possible), and its name should reflect what it does. If at all possible, try to keep the length of each sub so you can see the entire thing on one screen.
Capture data from the script now (specifically print out information from each small piece you're going to change), write tests for each small piece you're going to migrate to a subroutine or other library, ensure the new code does what the old code does, then move on to the next section. Now you've got regression tests.
| [reply] |
Re: How do I find the missing curly brace??
by LanX (Saint) on Dec 30, 2024 at 18:03 UTC
|
That's not trivial without knowing the previous version.
apart of using version control (like already mentioned)
For instant feedback
- run perl -c continuously in the background ( e.g. flycheck in emacs, default in Komodo)
- use automatic indentation while typing
For delayed analysis
- jump thru the last edits your editor recorded ( goto-last-change in emacs )
- indent the whole file, use perltidy if your editor doesn't support this ( indent-region in emacs) and do a visual check
- diff with the backup file your editor generated
- use tybalt89's suggestion to jump to the opening curly parsed by the editor for every closing one you find
update
perltidy has some additional features for code analysis, have a look.
IIRC there is also one to add extra info in a comment after each closing block.
| [reply] [d/l] [select] |
Re: How do I find the missing curly brace??
by tybalt89 (Monsignor) on Dec 30, 2024 at 16:59 UTC
|
In vim, add a closing brace to the end of the file, then put the cursor on that brace and in normal mode, press '%'. It should take you to the matching opening brace.
| [reply] |
|
this will bring him to the opening curley in the first level, not necessarily the one he's looking for.
| [reply] |
|
| [reply] |
Re: How do I find the missing curly brace??
by tybalt89 (Monsignor) on Dec 30, 2024 at 17:52 UTC
|
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11163431
use warnings;
my @what_lines;
@ARGV = '3raindeermaze.pl'; # FIXME
while( <> )
{
for ( split // )
{
/\{/ ? push @what_lines, $. :
/\}/ ? pop @what_lines : 0;
}
}
print "line numbers with unmatched { => @what_lines\n";
Comment out the ARGV line to use your file as the argument to the program.
( I just did that for testing. )
| [reply] [d/l] |
|
consider this convoluted example (Perl would catch this anyway)
sub bla {
print "yadda";
my %hash = {
foo => 1,
);
}
the problem is in line 3, but your code will report line 1.
and if you add a # } after a comment in line 2 it won't report anything.
| [reply] [d/l] [select] |
Re: How do I find the missing curly brace??
by naChoZ (Curate) on Feb 06, 2025 at 14:23 UTC
|
Lots of great answers and advice already that are worth considering.
Another simple technique that I use is from a vim feature using the [%] key. If you're on an opening (or closing) brace, bracket, or paren, hitting [%] will take you to the corresponding brace/bracket/paren. So, position yourself on an opening brace, take note of your indentation level, and hit [%]. If the brace it takes you to is not at that same indentation level, you've probably found your culprit.
It's not perfect, but it's really fast, even in a long script, and it's right often enough to make it worth trying that first.
| [reply] |
|
| [reply] |