You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Perrin Harkins <pe...@primenet.com> on 2000/06/01 08:06:12 UTC

Re: Human readable flatfiles

> I have a perl (non-modperl) program that needs some input data. Currently,
> it reads in the data by "require"ing another perl script that has
> statements to set the variables (as global variables). I did it this way
> so that I can easily edit the include file if I want to change values,
> and I can even put code in the include file to calculate values.
>
> But, I am finding that this does not work in modperl under "use strict".
> Apparently, code in a file called by require is not in the same variable
> scope. (If "use strict" is off, it works sometimes but other times the
> variables come out with the values from the previous invocation.)

You need to read up a little on modules and "require" in Perl5.

The quick and dirty solution is to use "do" instead of require.  That will
solve your immediate problem, but you'll still be reading the files every
time which might eventually become a performance hit.

What I do when I have things like config files is make actual unique
packages of them.  For example:

(In My/Module.pm)
package My::Module;
# don't use strict here
$foo = 7;

(In some other program)
use My::Module;
print "$My::Module::foo\n";

Honestly though, your example makes it look like you'd be better off with
dbm files and Tie::MLDBM or something.

- Perrin



Re: Human readable flatfiles

Posted by Perrin Harkins <pe...@primenet.com>.
Philip Mak wrote:
> I can't seem to get "do" to work. I did this:
> 
> my $series_name;
> do "series_$series.i"; # <-- note include filename depends on a variable
> print "$series_name\n";

Your lexical ("my") variable in the same scope is taking precedence, and
the "do' is not allowed to see lexicals in its enclosing scope.  If you
make $series_name a global, I think it will work.  The alternative is to
read the file yourself and eval it, which would allow it to see the
lexical.

> I also tried the package thing:
> 
> > What I do when I have things like config files is make actual unique
> > packages of them.  For example:
> >
> > (In My/Module.pm)
> > package My::Module;
> > # don't use strict here
> > $foo = 7;
> >
> > (In some other program)
> > use My::Module;
> > print "$My::Module::foo\n";
> 
> How would this work if the include filename has to depend on a variable? I
> think I have the parsing wrong; I kept getting error messages. e.g.
> something like:
> 
> use $series;
> print "$$series::series_name\n";

If it depends on a variable, replace the "use" with "require".  The
"use" statment is evaluated at compile time, and "require" at run time.

Keep in mind that require only loads each file once, so if you need to
show changes in these files that happen while the server is running this
won't work for you.

> > Honestly though, your example makes it look like you'd be better off with
> > dbm files and Tie::MLDBM or something.
> 
> The database files would have to be human readable though, such that they
> can be edited by a text editor. The data that I am making includes an
> index to content that is maintained by other webmasters. The other
> webmasters don't even know how to use a UNIX shell, so I have to keep it
> simple for them. If I used a binary file format I'd have to make them
> learn the tools for changing it.

Depending on how much of this data you have and how timely it has to be,
you could make a cron that crawls the text files every 5 minutes or so
and build a dbm with their data in it.

- Perrin

Re: Human readable flatfiles

Posted by Philip Mak <pm...@aaanime.net>.
On Wed, 31 May 2000, Perrin Harkins wrote:

Thanks for the reply. I have a few problems though:

> You need to read up a little on modules and "require" in Perl5.
> 
> The quick and dirty solution is to use "do" instead of require.  That will
> solve your immediate problem, but you'll still be reading the files every
> time which might eventually become a performance hit.

I can't seem to get "do" to work. I did this:

my $series_name;
do "series_$series.i"; # <-- note include filename depends on a variable
print "$series_name\n";

but $series_name comes out undefined, even though series_$series.i (in
this case, series_ranma.i) sets $series_name.

I also tried the package thing:

> What I do when I have things like config files is make actual unique
> packages of them.  For example:
> 
> (In My/Module.pm)
> package My::Module;
> # don't use strict here
> $foo = 7;
> 
> (In some other program)
> use My::Module;
> print "$My::Module::foo\n";

How would this work if the include filename has to depend on a variable? I
think I have the parsing wrong; I kept getting error messages. e.g.
something like:

use $series;
print "$$series::series_name\n";

> Honestly though, your example makes it look like you'd be better off with
> dbm files and Tie::MLDBM or something.

The database files would have to be human readable though, such that they
can be edited by a text editor. The data that I am making includes an
index to content that is maintained by other webmasters. The other
webmasters don't even know how to use a UNIX shell, so I have to keep it
simple for them. If I used a binary file format I'd have to make them
learn the tools for changing it.

-Philip Mak (pmak@aaanime.net)