Seriously, why should source filtering be bad for perl, but good for C?
In both cases the compiler might report an error where the mistake was inserted, rather than where it actually is. Also in perl, source filters screw up the line numbering (insert two lines in the code, and the line numbers for every compilation message, or
warn or
die afterwards will be off by two). A call to warn on the last line of your test will indicate an issue on line 35 of a 26 lines file...
The #line directive can solve most of those issues though, so if you turn
sub capitalize_next {
my ($thing) = @_;
uc inline increase($thing);
}
sub increase {
my ($foo) = @_;
++$foo;
}
into
sub capitalize_next {
my ($thing) = @_;
uc do { local @_ = ($thing);
#line 6
my ($foo) = @_;
++$foo;
#line 3
};
}
sub increase {
my ($foo) = @_;
++$foo;
}
Mistakes in the parameter list (eg increase(£thing)) will be marked as coming from line 3 (the line of the call), and mistakes from the function definition (eg ++£foo) will be reported as coming from inside the function definition.
local @_ makes it possible to access $_[0] and other values inside @_, while making line numbering easier (if ($foo) = @_ is replaced by ($foo) = $thing, the LHS comes from the function body but the RHS from the call, so where do you report an erreor?), but it probably slows things down... And since $foo = shift; uses @_ inside a function, but @ARGV elsewhere, it might introduce some interresting bugs.
Also note that the C preprocessor will only expand macros in code, not in comments nor in strings. Try this in your example:
sub capitalize_next {
my ($thing) = @_;
# uc inline increase($thing);
}
and you'll get some confusing errors. It's pretty easy to correct that one, but things might get difficult with strings and pod.