These are slides from a lecture on Red Flags in Programming that took place at an Israeli Open Source Developers meeting.
Red flags in programming are signs that you likely made a mistake with your application design or code.
Noticing and avoiding these mistakes help us write better code, at any language.
The subject related to mostly dynamic (higher level) languages, even though the sample code is in Perl.
2. Some words of caution...
We Perlers have a saying...
TIMTOWTDI
Be nice, no flaming
(only I'm allowed)
Not a Perl lecture, more like “bad
programming habits”
“Your mileage may vary”, “no batteries
included”, “don't drink and drive”
3. :
#1
ag
Repeated code
Fl
We overlook repeated patterns without even noticing
N more to read, understand, debug, test, maintain
N more places to have bugs!
Updating multiple places is error prone..
it's boring
distracting
lose focus
make mistakes
OMFG BUGZ!
Really, the worst thing a programmer can do
5. :
#2
ag
Reinvent the Wheel
Fl
You probably won't do it better... seriously
Development and maintenance grows because you
now have another (usually big) chunk of code
It's just repeated code, really...
6. :
#2
ag
Reinvent the Wheel
Fl
Modules
Libraries
Roles
Frameworks
Whatever the hell [Free] Pascal has
Write patches for what doesn't work for you
In extreme cases reinvent, but try to implement
as little as required.
Sometimes it's necessary to do it all from scratch:
Perlbal, Git, Linux :)
7. :
#3
ag
Switches without default
Fl
Not always wrong if ( is_alpha($num) ) {}
Usually wrong
Unexpected behavior elsif ( is_numeric($num) ) {}
Not the worst of things...
but please think of it
8. :
#3
ag
Switches without default
Fl
if ( is_alpha($num) ) {}
elsif ( is_numeric($num) ) {}
else {
}
9. :
#4
ag
Long Switches
Fl
Gross, really given ($foo) {
Not fun to read or debug
Not easily maintainable when (/^10$/) {}
It's basically a long if() when (/^20$/) {}
elsif()... even if seems when (/^30$/) {}
otherwise default {}
}
10. :
#4
ag
Long Switches
Fl
Dispatch tables my %dispatch = (
(if you can)
Use code references in 10 => CODEREF,
switches instead of code 20 => CODEREF,
itself
30 => CODEREF,
(if you can)
);
$dispatch{$num}->();
11. :
#5
ag
Try and Catch (workflow)
Fl
Try and Catch isn't for try {
workflow!!
That's what we have do_something_simple();
conditions and loops for } catch {
Internal functions should
print “Dear god, this is a
have return codes, not
throw exceptions really stupid thing to do!”;
PHP is fscking stupid }
Try and Catch is for when
external functions might
crash the program
12. :
#5
ag
Try and Catch (workflow)
Fl
Functions, subroutines, do_something_simple()
return codes!
Try and Catch is for or die “you suck!n”;
external programs or
things that are suppose to
crash
13. :
#6
ag
String Booleans
Fl
The string “false” is if ( $bool eq 'true' ) {
actually true => confusing!
Unnecessary value DO SOMETHING
check/comparison } elsif ( $bool eq 'false' ) {
Misses the point of
DO SOMETHING
booleans.
}
$bool = 'false';
if ( $bool ) { BUG }
14. :
#6
ag
String Booleans
Fl
Use real booleans $bool = do_that(@params);
Use zero (0), empty
strings and undefined
variables if ($bool) {
Sometimes you can't
# wheee... actual booleans
control it (using modules,
etc.) }
15. :
#7
ag
External Binaries
Fl
Compatibility problems
Portability problems
Unexpected results (`ps` for example is different on BSD
and has different command line switches)
Insecure!
16. :
#7
ag
External Binaries
Fl
Shared libraries
Bindings
APIs
libcurl is an example
Modules for running binaries more safely and controllably
(IPC::Open3, IPC::Open3::Simple, IPC::Cmd,
Capture::Tiny)
Taint mode (if language supports it – Perl does!)
Sometimes you can't control it (external binaries, closed
programs, dependencies at $work)
17. :
#8
ag
Intermediate Programs
Fl
Quite possibly insecure
Hard to maintain
No damned syntax highlighting!!!11
18. :
#8
ag
Intermediate Programs
Fl
If same language, use a subroutine/function
Different language && use an Inline module
Else, use templates
External file
19. :
#9
ag
Empty if() Clauses
Fl
Not DWIM/SWYM if ( $something ) {
Having an empty if() for
the sake of the else().. is # do nothing
horrible } else {
CODE
}
20. :
#9
ag
Empty if() Clauses
Fl
SWYM... please? if ( !$something ) {
Use unless() [Perl]
Don't really use unless() CODE
}
unless ( $something ) {
CODE
}
* Shlomi Fish is allowed to do otherwise :)
21. 0:
#1
ag
Array Counters
Fl
Some older languages foreach my $i ( 0 .. $n ) {
have no way to know how
many elements are in an $array[$i] = 'something';
array... $array_counter++;
Some people are too
}
used to older (more low
level) languages
Some people don't know
there's a better way
22. 0:
#1
ag
Array Counters
Fl
Higher level languages
have no problem
Using the number of the print $#array + 1;
last element
The number of elements
print scalar @array;
23. 1:
#1
ag
Variable abuse
Fl
Are you kidding me? sub calc_ages {
Awful awful awful
The reasons people get my ( $age1, $age2, $age3,
their hands chopped off in $age4 ) = @_;
indigenous countries
}
calc_ages( $age1, $age2,
$age3, $age4 );
24. 1:
#1
ag
Variable Abuse
Fl
That's why we have my @ages = @_;
compound data structures
(arrays, hashes) my %people = (
Even more complex data dad => {
structures, if you want
brothers => [],
sisters => [],
},
},
};
25. 2:
#1
ag
C Style for() Loop
Fl
Not really an issue for ( $i = 0; $i < 10; $i++ ) {
Harder to understand
And just not needed …
}
26. 2:
#1
ag
C Style for() Loop
Fl
Higher level languages foreach my $var (@vars) {
have better/cooler things
foreach (where available) ...
}
27. 3:
#1
ag
Goto Hell
Fl
OMGWTF?!1 if ( something_happened() ) {
But seriously folks, goto()
strips away all of our ability WHINE: say_it('happened');
to profoundly express my $care = your($feelings);
ourselves using languages
if ( !$care ) {
that finally let us
And yes, if you use goto WHINE;
goto(), I also think your }
mother is promiscuous
}
28. 3:
#1
ag
Goto Hell
Fl
DON'T USE GOTO! if ( something_happened() ) {
You're not a hardcore
assembly programmer, my $care;
you shouldn't have while ( !$care ) {
spaghetti code
say_it('happened');
Even xkcd agrees with
me! $care = your($feelings);
}
}
29.
30. ff
tu
s
od Dry, Rinse, Repeat
go
e
m
so
DRY (Don't Repeat Yourself)
Don't duplicate code, abstract it!
KISS (Keep It Simple, Stupid)
Don't write overtly complex stuff. Clean design yields
clean code. (yet some things are complex, I know...)
YAGNI (You Aren't Gonna Need It)
Start from what you need. Work your way up.