in reply to Convert BMP to HTML
Hi harangzsolt33,
Thanks for this! As others have said, it’s cool. Here’s some feedback on the Perl code itself. I hope you find it constructive and useful.
# Tested with TinyPerl 5.8 on Windows XP and Perl 5.004 on DOS.
These are now very old. I see from your home page that Perl is a hobby for you, so you’re not constrained by workplace policies to use any particular version. I strongly recommend you upgrade to an up-to-date Perl; this will allow you to take advantage of newer syntax features. For example, instead of local *FILE you can use lexical filehandles (as of v5.6). And a statement like my $F = defined $_[0] ? $_[0] : ''; can be simplified to my $F = $_[0] // ''; using the defined-or operator // (as of v5.10).
my $REF = ReadBMP('D:\\DESKTOP\\mandel3.bmp', 3); ReduceColorDistribution($REF); my $HTML = Canvas2HTML($REF); CreateFile('D:\\DESKTOP\\TESTING.HTM', $HTML); exit;
Putting driver code at file scope can potentially lead to hard-to-find bugs. Consider:
use strict; my $foo = 42; print "$foo\n"; # 42. No surprises here bar(); print "$foo\n"; # 17! How did that happen? # ...hundreds of lines of code... sub bar { ... $foo = 17; # Oops! Forgot "my" ... }
As you can see, use strict only gets you so far. Since $foo is declared at file scope, it remains visible/accessible to all subroutines in the rest of the file. This action-at-a-distance is what use strict is designed to prevent; so, let strict do its job by enclosing top-level code in its own block:
MAIN: # Label (not needed, just for documentation) { my $REF = ReadBMP('D:\\DESKTOP\\mandel3.bmp', 3); ReduceColorDistribution($REF); my $HTML = Canvas2HTML($REF); CreateFile('D:\\DESKTOP\\TESTING.HTM', $HTML); exit; # Not really needed either }
Now $REF and $HTML are invisible/inaccessible to the rest of the file.
if ($ERR > 5) { undef $HEADER; return 0; }
The error handling looks a bit strange, but what caught my eye was the undef $HEADER; statement. This looks like a hangover from C programming, where a malloc must eventually be followed by a free to prevent a memory leak. But Perl is garbage collected; here, $HEADER is a lexical variable so it will be marked as eligible for collection as soon as it goes out of scope (viz., when the return is executed). The undef does no harm, but it also accomplishes nothing here.
And lastly,
sub ReadBMP { ... }
The body of this subroutine is 377 lines long! Well, we’ve all written the sub that wouldn’t end from time to time, but when this happens you really need to go back and refactor it into separate subroutines. An excellent rule of thumb is that each subroutine should be fully visible on the screen without scrolling. Otherwise, you’re creating problems for your future self. For example, this loop:
while ($H--) {
caught my eye. Is the logic correct? (Because the operator is in postfix position, the condition is tested before the decrement is applied). On reflection, I think this is correct. But in order to check it, I wanted to see where $H was declared; and I had to go back 183 lines to find it! A maintenance nightmare.
Just my 2¢. Hope it helps,
Athanasius <°(((>< contra mundum | סתם עוד האקר של פרל, |
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: Convert BMP to HTML
by harangzsolt33 (Deacon) on Nov 02, 2022 at 20:37 UTC | |
by Athanasius (Archbishop) on Nov 03, 2022 at 12:12 UTC | |
by marto (Cardinal) on Nov 03, 2022 at 12:20 UTC |