I wrote a new module. I am not sure yet of its utility, but it is already on CPAN. It is named LaTeX::Writer::Simple. Also, not sure yet if its interface will be the one available at the moment.
But I would like to write about other thing: generating methods. It is cool to define methods during runtime:
BEGIN {
@EXPORT = (qw/document p/);
sub _def {
my ($name, $sub) = @_;
no strict 'refs';
my $x = "LaTeX::Writer::Simple::$name";
*$x = $sub;
push @EXPORT, $name;
}
my @nl_commands = (qw/part chapter section
subsection subsubsection caption/);
for my $c (@nl_commands) {
_def($c, sub { _newcommand($c, @_)."\n" });
}
...
It is just wonderful. And what I really liked was that
Test::Pod::Coverage detects those methods, and complains about their lack of coverage. Wonderful!
mmm, code generation
rjbs on 2008-06-10T01:27:54
I love generating named routines.
Perhaps you would enjoy
Sub::Exporter.
A few technical comments
btilly on 2008-06-10T13:31:43
I'm all for this technique, and I use it myself, so I'll just limit myself to some feedback on the code.
First, why are you using @EXPORT rather than @EXPORT_OK? That warning in Exporter is there for a reason.
Second, why are you using a BEGIN block? This code is in a module, which means that there is an implicit BEGIN block on your code already. Therefore adding another one is just semantic noise. You certainly don't need it for the sake of Exporter, since Exporter's import method isn't called until after your code is all done running. So get rid of your BEGIN block.
Third, there is no need to define _def as its own function. This is Perl, not JavaScript. If you move the body of _def inside of the loop and get rid of the function declaration entirely, then your closure will be formed properly and your code will get rid of one confusing indirection.
The problem with JavaScript is that var lexically scopes to the nearest function call, not the nearest block. Which means that if you declare a variable within a loop, it is not scoped to the loop iteration, but the function call. So if you try to create 5 closures in a loop, you wind up creating one closure 5 times. This problem does not exist in Perl since my scopes variables to the nearest bock.
This is a serious misfeature in JavaScript. Which is why JavaScript 1.7 lets you achieve the same effect by using the let declaration instead of the var declaration. Unfortunately JavaScript 1.7 is not well supported in the real world yet so you can't use it. (Which is to say that it is supported in Firefox 2.0, but not in Internet Explorer.) But still there is the hope that some day you can just declare your variables in JavaScript with let and forget about this problem there, just like you can today in Perl.
the _def function
ambs on 2008-06-10T13:41:01
Well, the _def function was there just to make it easier to read, but you are correct that it is an extra indirection.
Thanks for the comments
;)
Re:the _def function
ambs on 2008-06-10T16:38:24
Oh, and there is another reason about defining a _def. I am using this code to define functions in four or five different places. This makes it easier to maintain.
Sorry for the indirection ;)