Your idea seems to capture the spirit of the best suggestions in this thread well.
I was thinking a little more about it and came up with this::
use constant ATTACK_TYPES => [
{
type => 'light',
damage => 1,
speed => 5,
},
{
type => 'fast',
damage => 1,
speed => 7,
},
{
type => 'heavy',
damage => 2,
speed => 4,
},
];
foreach my $attack ( @{ATTACK_TYPES()} ) {
my $name = "new_$attack->{type}";
{
no strict 'refs';
*{$name} = sub { return shift->new(%$attack) };
}
}
Which seems too clever on the one hand, but on the other hand does a nice job of separating configuration data from
code. The fact that it mostly eliminates the pitfalls of "Don't Repeat Yourself" is a bonus. But the real advantage is what can come next: The next logical step would be to store the attack types as a JSON file, and then process it like this:
use IO::All;
use JSON 'decode_json';
use constant ATTACK_PARAMS => [ qw/ type damage speed / ];
my $attack_types
= decode_json( io('attacks.json')->slurp );
foreach my $attack ( @$attack_types ) {
exists $attack->{$_} or die "Malformed attack type: $_\n"
for @{ATTACK_PARAMS()};
my $name = "new_$attack->{type}";
{
no strict 'refs';
*{$name} = sub { return shift->new(@{$attack}{ATTACK_PARAMS()}
+) };
}
}
And now someone who doesn't care to learn a lot about programming could still manipulate the game's parameters without wasting your time.
|