First question: a long, long time ago you asked a similar question. I recommened (and still do) Config::General. However, Config::General only works on a file. I did give you a work around - subclass and override. Now, personally i would prefer for Config::General to accept an array ref, but by using copy-and-paste, you can rewrite its _open() method to accept an array instead:
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; }
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:
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;
This could definitely be abstracted further, but it should give you an idea to run with for now. Good luck!

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)

In reply to (jeffa) Re: Email "Reflector" design snags by jeffa
in thread Email "Reflector" design snags by hacker

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.