collect '//server/corion/images/';
output '/home/corion/imagestream/output';
size 160;
size 640;
exclude_tag 'private';
prefer '.svg' => '.jpg';
prefer '.svg' => '.png';
prefer '.cr2' => '.jpg';
####
sub collect($) {
push @image_directories, @_;
};
sub size($) {
push @image_sizes, @_;
};
sub prefer($$) {
push @prefer_format, [@_];
};
...
####
my $spec = {
collect => {
name => 'collect',
arg_count => 1,
desc => 'A directory from which to collect images',
},
prefer => {
name => 'prefer',
arg_count => 2,
desc => 'Prefer this image format over files with the same name in other formats',
},
# ...
};
####
my %handler;
for my $item (values %$spec) {
my $n = $item->{name};
my $fetch;
$result->{$n} = [];
if (0 == $item->{arg_count}) {
$fetch = sub() { push @{ $result->{$n}}, 1; };
} elsif (1 == $item->{arg_count}) {
$fetch = sub($) { push @{ $result->{$n} }, @_; };
} elsif (2 == $item->{arg_count}) {
$fetch = sub($$) { push @{ $result->{$n} }, [@_]; };
} else {
$fetch = sub($;) { push @{ $result->{$n}}, [@_]; };
};
$handler{$n} = $fetch;
};
# Install the subroutines
for (keys %handler) {
no strict 'refs';
*{$_} = $handler{ $_ };
};
# "execute" the config:
my $cfg_str = join ";\n",
"package " . __PACKAGE__,
"#line $config_source#1",
"$config_data",
"1";
#warn $cfg_str;
my $ok = eval $cfg_str;
my $err = $@;
if ($ok) {
return $result
} else {
warn $err;
return
};
####
use Scope::Guard qw(guard);
{
my @guards;
for (keys %handler) {
# Save the old state:
my($k,$p) = ($_,\&$_);
push @guards, guard {
# restore the old state
*$k = $p;
};
# Install our new handler
*$_ = \&$handler{$_};
}
# "execute" the config
# ...
}
# Scope::Guard executes our guard blocks here
####
local @{My::App}{keys %handler} = values %handler;
# Can't modify glob elem in local at ...
####
for my $n (keys %handler) {
local *$n = $handler{ $n };
}
# no handlers defined here anymore
####
my ($ok,$err);
my $cfg_str = join ";\n",
"package " . __PACKAGE__,
"#line $config_source#1",
"$config_data",
"1";
my @handlers = keys %handler;
{
no strict 'refs';
# We don't want to introduce another scope, as that will
# negate the effect of the local:
NEXT:
my $n = shift @handlers;
local *{$n} = $handler{ $n };
goto NEXT
if @handlers;
$ok = eval $cfg_str;
$err = $@;
}
if ($ok) {
return $result
} else {
warn $err;
return
};
####
...
{
my $guard = local_install_subs \%handler;
$ok = eval $cfg_str;
$err = $@;
}
...