Rails fans are understandably proud of the magic metaprogramming facilities of Ruby, the database introspection capabilities of ActiveRecord, and the fact that the most basic model class is only two lines long (at least in every tutorial I’ve seen).
I say that’s two lines too many.
Here’s how to have zero-line model modules in Perl — as many as you want. (If you have a complete CRUD application, you can use the same idea to generate RESTful controllers, too.)
I started by defining a base model class:
package MyApp::Model;
sub new
{
my $class = shift;
(my $name = $class) =~ s/__PACKAGE__:://;
bless \$name, $class;
}
sub name
{
return ${ +shift };
}
1;
Sure, it doesn’t do anything (such as connect to a database), but it serves
the same purpose as ActiveRecord::Base in Rails.
Then I wrote the main module for my application, MyApp. (Hey,
it’s Friday afternoon. I leave my creativity for the code.) All it has to do
is load two modules:
package MyApp;
use GenModel;
use MyApp::Model::Prufrock;
1;
All that’s left (besides the mysterious GenModel) is myapp.pl:
#!/usr/bin/perl
use strict;
use warnings;
use MyApp;
my $model = MyApp::Model::Prufrock->new();
print "My model's name is: ", $model->name(), "!\n";
Now I have written GenModel, but I haven’t written
MyApp::Model::Prufrock. The only references to it in my entire
source tree are in the use line of MyApp and in the
line that creates $model in myapp.pl.
I realize full well that a good model class for a complex application needs a few more lines of code, but why even write the model class until you really need it?
Of course all of the magic is in GenModel, which I don’t want
to show quite yet. It’s a well-spaced screen full of fairly simple Perl code
that doesn’t use eval or any other code generation tricks you
might think. It’s no source filter and it doesn’t replace any of Perl’s
syntax.
I’ll post the code in a couple of days. It uses a technique in chapter 8
of Perl Hacks.
Meanwhile, I’d like to see a similar Ruby version that doesn’t use any
eval either. (I have an idea how to make it work, but not
without eval.)

Heya chromatic! Fortunately, Bryan Evans is on the case with the DrySQL plugin for Active Record.
Active Record doesn't need to use eval at all since Ruby has such niceties as define_method, const_missing, and method_missing. However, define_method captures scope so when classes are reloaded in development mode you have a memory obesity issue that eval doesn't suffer.
You can do
class Prufrock < ActiveRecord::Base; endor
const_set some_model_name, Class.new(ActiveRecord::Base)or even
then
Models::PrufrockorModels::WhateverElseCheers!
DrySQL to the rescue: http://drysql.rubyforge.org/
Man, years of submerging in perl still leave me in a desert when looking at your code. Another reason for me to like ruby and ror. I like simplicity and clearness.
chromatic,
were you trying to show this to be more convenient than Ruby/RoR?
Man, I don't know. As someone who does both perl and ruby, this may not be the best example! :)
Interesting and perhaps a bit far out there with seeing GenModel.Have you reviewed Data::ObjectDriver?
Why is using eval so bad in this case? What you get is code (classes) generated at run time. Isn't whether that is done via an eval or meta model poking just a (language specific) implimentation detail?
i really enjoyed this article and am hoping you post the follow-up about GenModel soon ...