I think you're missing the point. The idea is simply that anything you can do via code generation could be done using subroutines instead, provided you are using a high-level dynamic language like Perl.
Well, you condemned code generation in general, so I gave several examples of where I found it appropriate and beneficial. It's true that the common denominator in each example was C, but there are times I've used generators for Perl too.
Generating a lookup table from an HTML page is basically data manipulation and could be done as a config file rather than code.
Maybe, but then I'd have to write C code to open the file, parse each line, and build up a data structure for the codes and strings dynamically. Pain in the ass, and much, much less efficient than the static array generated by the Perl script.
Generating documentation is, well, documentation. It's human-readable text, so you can't handle it as a library call the way you could with other code generation situations.
The Perl script generated POD, which is a form of "code," is it not?
I understand what you're saying, though. But there are times you need code that's predictable enough to be automatically generated but not predictable enough to be encapsulated away by a few routines. Yes, this is much rarer in a language like Perl, but it still happens.
I don't know enough about XSUB to comment on your last example, except to say that the rules are different in static languages like C where you really may not be able to do certain things as a subroutine.
Converting linked lists to arrays on return, making sure everything gets garbage collected correctly, and giving each XSUB a shorter, more Perl-ish name were just a few of the problems it solved quickly for me.
Class::DBI does this in perl, and it uses code generation, but it does the generation on the fly at run-time and doesn't produce an intermediary source code that can be hand-edited and get out of sync. The use is still questionable in my opinion, but not as bad as it could be.
The generated code getting edited and becoming out-of-sync with the generator is only problematic if you don't know what you're doing. Hunt & Thomas described (The Pragmatic Programmer, pp. 103-05) two types of code generators: active and passive. Passive generators generate something once, then the output is taken and used and modified as needed (e.g., the XSUB generator described above). An active code generator can be used again and again as its sources of input change (e.g., the Winsock error lookup table generator described above).
Just know which type of generator you're going to write and what you plan on doing with its output, and everything should work fine.