This post originated from an RSS feed registered with Ruby Buzz
by Daniel Berger.
Original Post: mkmf and erb
Feed Title: Testing 1,2,3...
Feed URL: http://djberg96.livejournal.com/data/rss
Feed Description: A blog on Ruby and other stuff.
Today I happened to be thinking about Rails, erb, and templates. Then I happened to be thinking about mkmf and mkmf2. Then I happened to look up at my bookshelf and see Jack Herrington's Code Generation in Action. I then thought to myself, "Self, there must be a way to combine these two things to make something better."
Ok, I have a strange mind. Bear with me.
If you look at the source code for mkmf.rb (be sure to put sunglasses on first), you'll see that lots of little tidbits of C code are being dynamically generated. Stuff like this:
#include <stdio.h>
/*top*/
int conftest_const = (int)(#{const});
int main() {printf("%d\\n", conftest_const); return 0;}
}
That code is then written to a temporary file and compiled by shelling out with a system() command, and a true or false result is determined.
This is where I thought erb might come in handy. Instead of having all these little strings being dynamically generated, how about we use a template? Here's one I've started:
#include <stdio.h>
<% if @headers %>
<% @headers.each do |header| %>
#include <<%= header %>>
<% end %>
<% end %>
int main(){ return 0; }
Then the have_header() method, for example, could be reduced to this:
# Let's assume we have an @erb object already created somewhere
def have_header(*header_files)
@headers = *header_files
File.open('tmp.c'){ |fh| fh.write @erb.result(binding) }
system("#{cc} #{cflags} tmp.c')
end
The last two lines would probably be reduced to a single helper function in real code. Logging would require stripping out the excess blank lines, but that's nothing too difficult.