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

I have a hash setup in a file, how do i get it out? it tried:

open(FILE, "filename");
%myhash = eval(<FILE>);
close(FILE);


but that doesn't do anything useful

Replies are listed 'Best First'.
Re: getting hashes out of config files
by Fastolfe (Vicar) on Oct 24, 2000 at 23:25 UTC
    You need to read data from the file before you try to operate on it. eval operates on $_ in lieu of arguments, so you need to put something into $_ first:
    open(FILE, "< filename") or die "filename: $!"; { local $/; $_ = <FILE>; } close(FILE); eval;
    Or you could just use Perl's do function:
    do "filename" or die "filename: $! ($@)";
(Ovid) Re: getting hashes out of config files
by Ovid (Cardinal) on Oct 24, 2000 at 23:27 UTC
    Hmm, your code snippet doesn't actually read from the file. Plus, if you're using Data::Dumper, you're going to have problems figuring out where the stuff begins and ends. If you only have one hash in a file, you could try to following (untested)
    { local $/; open FILE, "<$filename" or die "Can't open $filename for reading: +$!"; %myhash = eval ( <FILE> ); close FILE; }
    The above snippet is just a guess, of course.

    You should look into FreezeThaw for storing data of this type in a file. Each data structure can be reduced to a single string (freeze) and then restored (thawed) quite easily.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just go the the link and check out our stats.

RE: getting hashes out of config files
by arturo (Vicar) on Oct 25, 2000 at 00:40 UTC
    Assuming "foo.dat" is the file which consists of what Data::Dumper stored, AND that "%hash" is the name of the hash defined in that file, all you need to do is
    use strict; use vars '%hash'; do('foo.dat');
    And the hash should be set. I point out the use strict and use vars because I was bitten just yesterday by the problem that since the data resides in a separate file, do(file) doesn't work well with lexical variables (those created with my). See perlfunc:do for more info, and thanks to merlyn, dchetlin, and tye for helping sort me out on this issue.

    (Oh yeah, and check the file Data::Dumper created to make sure it defines '%hash')

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

      that works nicely, except for one problem:

      do('$filename');

      doesn't seem to work, however if i type the path and file instead of using $filename variable it works ... is there a way to use the $filename variable with the do function?

      it tend to be much more usefull to use a variable ... its a lot sorter thanks in advance
        You're using single quotes, which do not do variable interpolation. Thus, you are attempting to open the file named $filename (literally). Remove the quotes entirely, as they're unnecessary, or use double-quotes, which will correctly do interpolation:
        do($filename) or die "..."; do("$filename") or die "...";
RE: getting hashes out of config files
by princepawn (Parson) on Oct 24, 2000 at 23:23 UTC
      I recommend a module Config::General.
      Simple API, flexible behaviour.
      Great to parsing configfiles in Apache style.
RE: getting hashes out of config files
by lachoy (Parson) on Oct 24, 2000 at 23:45 UTC

    Note that Data::Dumper typically operates on references, so you'll normally get a reference ($my_hash) rather than a hash (%my_hash) back from the eval, which other folks have pointed out is not specified correctly anyway.

    Also, unless you specified the variable when saving the hashref via Data::Dumper, you'll probably need to do something like:

    my ( $my_hash ); { no strict 'vars'; $my_hash = eval $text_I_read_in; die "Error reading in text: $@" if ( $@ ); }

    So you can ensure that whatever variable created by the dumping procedure (usually something like $VAR1) doesn't cause use strict to have a fit. You are using use strict, right? :)

RE: getting hashes out of config files
by Anonymous Monk on Oct 24, 2000 at 23:18 UTC
    btw: i used datadumper to put it in the file .. i don't know if that changes the solution any.