On Mon, 10 Nov 2008 18:57:00 +0000, max psykx wrote:
> whats perl inspiring you to do at the moment?
>
> feel free to answer again if I asked you at the monks meeting for
> the benefit of those who weren't there (or weren't listening ;) )
Here's the metaprogramming that I explained very badly at the
meeting. I've got a system which contains a hierarchy of "resources",
and I want to be able to create new leaf resources without having to
worry about whether the supporting hierarchy is in place for them. I
started off with a bunch of methods which were all very similar;
figure out what the parent resources should be, create them if
necessary (via one of the same family of methods, with potential
calls all the way up the hierarchy), extract the resource properties
from somewhere suitable, and finally create the resource if it
doesn't already exist. Like this:
sub A_resource_create_magazine_archive_group{
my($self,$mag,$year,$sess_idval)[EMAIL PROTECTED];
my $acronym=$mag->acronym_ics;
# Return the Id if it already exists
my $nodename="product/$acronym/archive/group-$year";
if(my $idval=$self->A_resource_idval_read($nodename,$sess_idval)){
return $idval;
}
# Extract relevant details
my $acronym_archive=$mag->acronym_archive;
# Make sure the parent exists
my $parent_idval
=$self->A_resource_create_magazine_archive($mag,$sess_idval);
$sess_idval||=$self->A_session_idval;
# Create the reosurce, cache the Id and return it
my $res_idval=$self->resource_create($sess_idval,{
'IOP:nodename' => $nodename,
resourceType => 'grouping',
name => "$acronym archive $year group",
description => "$acronym_archive $year grouping",
year => $year,
},[$parent_idval]);
$self->A_resource_idval_cache($nodename,$res_idval);
}
I realised that I was repeating myself far too much, so I wrote a
little method creation sub which took care of all the make work,
leaving me with just the differences between the various resources to
worry about:
_A_resource_create_template(
name => 'magazine_archive_group',
params => 'mag,year',
nodename => 'product/$mag.acronym_ics/archive/group-$year',
parent => 'A_resource_create_magazine_archive($mag)',
properties => {
resourceType => 'grouping',
name => '$mag.acronym_ics archive $year group',
description => '$mag.acronym_archive $year grouping',
year => '$year',
},
);
That results in exactly the same method as the longwinded way I started
with, but with a lot less typing and thinking required, both when
writing the method, and more importantly, when maintaining it. I
invented yet another template language to deal with setting property
values, including method calls, but it seemed worthwhile. There's 120
lines of code in the metamethods themselves, which is why I haven't
included them here. I'm not sure whether I managed to save quite that
much code over the hand-coded methods, but I've definitely saved lots
of maintenance time. Out of the 10 or so methods which were converted
to this scheme, about half had serious errors which were obscured by
all of the infrastructure. Since then, the roster has increased by 50%,
all added with minimal effort, and a vastly reduced risk of errors
compared to hand-coding. I think the time spent writing this system was
well worth the effort, and well, meta-programming is just so much fun!
--
Peter Haworth [EMAIL PROTECTED]
"not all early design decisions are the right ones
-- whether [they] be tattoos or a variable declaration syntax."
-- Damian Conway
_______________________________________________
BristolBathPM mailing list
[email protected]
http://mailman.bristolbath.org/mailman/listinfo/bristolbathpm