http://www.perlmonks.org?node_id=287493

sutch has asked for the wisdom of the Perl Monks concerning the following question:

I'm developing a package that will include some data files that will be read in for some operations. I've looked through some packages from CPAN and cannot find any packages that do such a thing.

Is there a recommended location for placing data files that are bundled with a package, or should the data be embedded within a perl module?

If the data file is to reside in the package's subdirectory of the lib directory, is there a method for determining the path to the package?

Thanks.

Replies are listed 'Best First'.
Re: Data files included in a package
by wufnik (Friar) on Aug 28, 2003 at 19:35 UTC
    hola;

    i have always found
    __DATA__
    to be useful for including data within scripts/modules;
    simple scenario:

    you want to use 'test' data if a file is not specified.
    my @lines # where we want to store the data my $testfile = shift; # populate lines in dull bit here if testfile is a file chomp (@lines = (<DATA>)) unless -f $testfile; print join " * ", @lines; __DATA__ in the world of the mules there are no rules
    hope that helps,

    ...wufnik

      wufnik++. Note that only the last __DATA__ section read in a namespace is visible. Be aware that __END__ sections are always in package main::.

      After Compline,
      Zaxo

Re: Data files included in a package
by bart (Canon) on Aug 29, 2003 at 01:11 UTC
    Well, yes, a subdirectory of the library's own subdirectory looks OK to me. But maybe that's just me. Actually, any place where that package could reside in @INC is fine by me, but don't expect any help from perl to locate it from you. You'll have to emulate what perl does in require, scanning through @INC and seeing if the data files can be found. Or you could demand that the data files have a fixed relative position toward the location of the module file itself. You decide.

    But don't take my word for it. Take a look at a well-established module from CPAN: XML::Parser. Just look at the character encoding files ("*.enc") that XML::Parser::Expat, the underlying parser engine, uses, and how it locates them in @INC — source of XML/Parser/Expat.pm, populating @Encoding_Path.

    Addendum.

    is there a method for determining the path to the package?
    Take a look at %INC. If your module is Foo::Bar then it'll be under $INC{"Foo/Bar.pm"}, even on systems where the file path separator isn't a slash, like Windows (actually a backslash, though a slash works too) and the Apple Macintosh, where it is ":" (!).
Re: Data files included in a package
by hardburn (Abbot) on Aug 28, 2003 at 19:29 UTC

    I've done something similar for some private modules. Ways I've come up with are:

    • Make the data file into a package of its own. For instance, a config file for My::Foo becomes My::Foo::Config, and My::Foo just uses it.
    • If the data file can't be turned into a package for whatever reason, then use the Makefile.PL to ask the user at install-time where the data files will be located. Then have Makefile.PL generate the config module like above which contains the absolute path to the data.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: Data files included in a package
by williamp (Pilgrim) on Aug 28, 2003 at 22:22 UTC
    Flat files are OK for small jobs. Up the scale comes the DB_File and then a database. DB_File is a nice way or holding data you want to use from run to run. To find where your files are use File::Find Hope this helps
      File::Find isn't a realistic solution. Users probably won't accept the delay of searching the filesystem for the data file(s) each time the package is used.