in reply to Email "Reflector" design snags
For your second question, why not use a data structure to check for the existence of each conf variable. You could have a hash whose key is the config var in question, and maybe it points to another hash with keys such as required, maximum, or regex. If there is an error, put that error in an array or a hash, then, if there are elements in that key or hash, you know that the config is invalid. Here is a slightly tested but working example just to give you an idea:use strict; use Data::Dumper; my (undef, @conf) = split ($/, " <template> url = http://www.foo.com/ # URL to fetch AvantGo = No # apply heuristics maxdepth = 2 # depth to traverse bpp = 4 # pits-per-pixel compression = zlib # or 'DOC' or 'None' title = My Document # title of output </template> " ); my $conf = MyConfig::General->new(\@conf); print Dumper {$conf->getall}; package MyConfig::General; use base 'Config::General'; sub _open { my ( $this, $arrayref ) = @_; my ( @content, $c_comment, $longline, $hier, $hierend, @hierdoc ); local $_; for (@$arrayref) { chomp; if ( !$hierend ) { s/(?<!\\)#.+$//; next if /^#/; next if /^\s*$/; s/\\#/#/g; } if (/^\s*(\S+?)(\s*=\s*|\s+)<<(.+?)$/) { $hier = $1; $hierend = $3; } elsif ( defined $hierend && /^(\s*)\Q$hierend\E$/ ) { my $indent = $1; $hier .= " " . chr(182); if ($indent) { foreach (@hierdoc) { s/^$indent//; $hier .= $_ . "\n"; } } else { $hier .= join "\n", @hierdoc; } push @{ $this->{content} }, $hier; @hierdoc = (); undef $hier; undef $hierend; } elsif (/^\s*\/\*/) { if (/\*\/\s*$/) { $c_comment = 0; } else { $c_comment = 1; } } elsif (/\*\//) { if ( !$c_comment ) { warn "invalid syntax: found end of C-comment without previ +ous start!\n"; } $c_comment = 0; } elsif (/\\$/) { chop; s/^\s*//; $longline .= $_ if ( !$c_comment ); } else { if ($longline) { s/^\s*//; $longline .= $_ if ( !$c_comment ); push @{ $this->{content} }, $longline; undef $longline; } elsif ($hier) { push @hierdoc, $_; } else { if ( !$c_comment ) { my $incl_file; if ( /^\s*<<include (.+?)>>\s*$/i || ( /^\s*include (.+?)\s*$/i && $this->{UseApacheInclude} ) ) { $incl_file = $1; if ( $this->{IncludeRelative} && $this->{configpath} && $incl_file !~ /^\// ) { $this->_open( $this->{configpath} . "/" . $incl_file ); } else { $this->_open($incl_file); } } else { push @{ $this->{content} }, $_; } } } } } return 1; }
This could definitely be abstracted further, but it should give you an idea to run with for now. Good luck!my @errors; my %valid = ( url => { required => 1, regex => qr{^http://[\w./]}, }, maxdepth => { required => 1, regex => qr{^\d+$}, maximum => 10, }, ); my $conf = MyConfig::General->new(\@conf); my %conf = $conf->getall; my %tmpl = %{$conf{template}}; for (keys %valid) { my $v = $valid{$_} or next; if ($v->{required}) { unless ($tmpl{$_} !~ /^\s*$/) { push @errors, "$_ is missing" } } if ($v->{regex}) { unless ($tmpl{$_} =~ /$v->{regex}/) { push @errors, "$_ has invalid format: $tmpl{$_}" } } if ($v->{maximum}) { unless ($tmpl{$_} <= $v->{maximum}) { push @errors, "$_ is too large: $tmpl{$_}" } } } print Dumper \@errors;
jeffa
L-LL-L--L-LL-L--L-LL-L-- -R--R-RR-R--R-RR-R--R-RR B--B--B--B--B--B--B--B-- H---H---H---H---H---H--- (the triplet paradiddle with high-hat)
|
|---|