18 Nov 2002 jbucata   » (Apprentice)

Quines

A quine is a program that prints its own source code as output. (See here and here if you're new to them.) At work, I recently wrote a Perl program that makes use of quines.

For a project I'm loaned out to (not one of my several normal ones), I'm generating a PL/SQL stored procedure to do some Oracle database work. The procedure has very repetitive almost-identical blocks of code that can't be factored meaningfully, unless I switch to dynamic SQL--and given dynamic SQL in PL/SQL, I'd rather copy and paste large swaths of code. Rather than cranking out all this code once manually, I wrote a simple Perl script to spit it out. If I need to make changes to something, I just change the Perl script and rerun. Consequently, that Perl script is important, since I don't want to ever have to modify the stored procedure code by hand. I don't know if the rest of the team has any source-code control (I rather suspect not), and if they do I don't have access to it. I wanted to find a way to make sure that the Perl script would always be available to somebody who had the stored procedure source (which they could always get out of the Oracle data dictionary if they needed to).

I hit upon the idea of putting the Perl script in a comment block near the top of the procedure. It would be an easy edit in vi to read the source in and shove the comment delimiters at the front of each line, but that's editing the stored procedure, which I said I don't ever want to do. It could break the procedure if something is mistyped, and it's a manual step that later tinkerers might or might not do, if they happened to receive the script by other means and didn't see that the original's output included a block of comments with the script source. So somehow I had to have the script place the script source in the comments for the invoker without the invoker needing to do anything special... et voila, the idea is born.

The biggest problem was finding a quine that would let me embed a code intron. Some quines will let you store arbitrary text and have it reproduced along with the program itself; what I needed was for arbitrary code--the code to generate the stored procedure--to be reproduced and run. In fact, I also needed a way to have the printed source be modified to add the comment delimiters and indentation in front.

I found this nugget by njaharve@uwaterloo.ca:

#!/usr/bin/perl
$_=<<'eof';eval $_;
print "#!/usr/bin/perl\n\$_=<<'eof';eval \$_;\n${_}eof\n"
eof

which is really straightforward and is probably what I would have come up with myself. The thing to note here is that the code within the eval can be anything you want; whatever you put there gets executed and printed (when you run the magic print statement within the block of code). So I took this quine and turned it into a quasiquine that prints the stored procedure, with the script source (after applying :%s/^/\t--/ to it) inserted near the top.

Church

Had a very nice weekend. Two pastors who used to be at my church but moved away came back and did a seminar here. Life-changing stuff. Their messages managed to help answer some big questions about faith that I only recently realized I needed answers to. It's like they decided to spend the entire weekend teaching about what I've been going through--without them knowing anything about my situation beforehand. I only wish I didn't have to get back to the daily routine of work and such--going to church, when it feeds you, is way more fun (yes, even than writing quines).

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!