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

I'm writing a text based RPG in perl and I am trying to find a way to set it to write a config file so I can have a save and load feature. While looking on here a couple of months ago I saw that someone was talking about the Config::Simple module, so I downloaded it and installed it I followed the syntax on http://search.cpan.org/~sherzodr/Config-Simple-4.59/Simple.pm but it does not work. I have the following code for setting up and writing the config file:
use Config::Simple; our $cfg; $cfg = new Config::Simple(syntax=>'simple'); $cfg->autosave(1); $cfg->param("player", "@player"); $cfg->param("quest", "$completed_quests"); $cfg->param("items", "$special_item") $cfg->param("enemy", "@enemy"); $cfg->param("class", "$class"); $cfg->write("~/.kenesis");
I'm hoping someone more experienced/wiser than me here can figure out what I did wrong, or what I am missing.

Replies are listed 'Best First'.
Re: Trouble working with Config::Simple
by kyle (Abbot) on Jun 30, 2008 at 19:16 UTC

    Perl doesn't do tilde expansion—that's a shell thing. Your last line would need to be:

    $cfg->write("$ENV{HOME}/.kenesis");

    Also, you're missing a semi-colon on the $special_item line.

    Update: Config::Simple apparently reports errors (in write(), for instance) with false return values. As such, you could have known what was up with code like this:

    $cfg->write("~/.kenesis") or die $cfg->error();

    Reports:

    '~/.kenesis' couldn't be opened for writing: No such file or directory
      '~/.kenesis' couldn't be opened for writing: No such file or directory

      I doubt, though, that this message would have helped a lot here.  Someone starting out with the conviction that ~ (tilde) would work from Perl like it does in the shell, would probably have begun wondering why their home directory isn't writable for themselves, or some such... :)

        The message is telling exactly what's wrong. There is no directory '~'. It doesn't say anything about a "permission denied". So, there's no need to wonder.

        I think if it would do a ~ expansion, it should state the expanded path in the error message (just like the shell does).

        $ touch ~/test.txt $ chmod a-w ~/test.txt $ echo "string" > ~/test.txt bash: /home/user/test.txt: Permission denied $

        That's true, but it would have been a good clue to us. I started answering the OP without even knowing how Config::Simple reports errors. Having the error in front of me would have gotten me to the answer faster.

Re: Trouble working with Config::Simple
by ysth (Canon) on Jun 30, 2008 at 19:19 UTC
    Unless Config::Simple has special code to handle it, you shouldn't use "~" in your filename. When you use that from shell commands, it's the shell's job to expand it to your home directory, but it doesn't work in arbitrary filenames not expanded by the shell.

    A quick fix would be to do my $rc_dir = glob("~"); and use $rc_dir, though something like use File::HomeDir; my $rc_dir = File::HomeDir->my_data; would be better.

Re: Trouble working with Config::Simple
by toolic (Bishop) on Jun 30, 2008 at 19:20 UTC
    it does not work
    That is not very descriptive. What exactly does not work?

    Do you see no output file named ".kenesis" in your home directory? Neither do I when I run your script. But, if I change:

    $cfg->write("~/.kenesis");

    to:

    $cfg->write("/home/toolic/.kenesis");

    I do get a file named ".kenesis" in my home directory. Perhaps Config::Simple does not expand the tilde properly.

Re: Trouble working with Config::Simple
by psini (Deacon) on Jun 30, 2008 at 19:19 UTC

    I'm not sure you can use autosave if you have not loaded a config file, but it could be useful if you tell us what goes wrong:

    • it throws an error message?
    • Which error(s)?
    • Adding use strict; use warnings; does something change?
    • It does not save to the file?
    • Or save wrong values?
    • Which values?

    Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."

      I've commented out the autosave line and still no go As for your other questions No it does not throw and error message, it just continues on like nothing is wrong The actual program does have use strict; use warnings; I use them on all my Perl scripts. I just posted the lines of code that deals with Config::Simple to cut down on pointless code being posted. The problem is that I can't get it to create the ".kenesis" file.
Re: Trouble working with Config::Simple
by vendion (Scribe) on Jul 09, 2008 at 01:55 UTC
    Well thinks to everyones help and some tinkering I got it to create the file and write to it, but now I have having trouble getting it to read from the file
    sub load_game { $cfg->read("'$ENV{HOME}/.kenesis'"); @player = $cfg->param("player"); @enemy = $cfg->param("enemy"); $completed_quests = $cfg->param("quest"); $special_item = $cfg->param("items"); $class = $cfg->param("class"); #main_menu(); print "@player\n"; print "@enemy\n"; print "$completed_quests\n"; print "$special_item\n"; print "$class\n"; exit; }
    I get the following error Can't call method "read" on an undefined value at kenesis.pl line 93, <STDIN> line 1.. The thing is all of my variables are defined
    our @player; our $completed_quests = 0; our $special_item = "none"; our @enemy; our $class = "null"; our $cfg;
    .
    The line that the error is complaining about, line 93, is this line $cfg->read("'$ENV{HOME}/.kenesis'");

      Quite possibly &load_game is being called before $cfg becomes a Config::Simple object.

      [...] all of my variables are defined
      our @player; our $completed_quests = 0; our $special_item = "none"; our @enemy; our $class = "null"; our $cfg;

      From that snippet, I see some of variables being declared but not defined, namely $cfg. Missing also from the snippet are the stages at which &load_game and &Config::Simple::new are being called.

      $cfg->read("'$ENV{HOME}/.kenesis'")

      What's with two kinds of quotes around file name? Is a file name actually being surrounded by single quotes (on the file system)?

        The variables are defined before everything else, the only reason the the arrays are not defined there is because they are defined later after the class as been selected. the &load_game code comes after everything is defined. The two quotes around the file name $cfg->read("'$ENV{HOME}/.kenesis'") is the only way I was able to get $cfg->read to see the .kenesis file, I'm not sure why I had to though.
        I guess it would be easier for people to review the whole code, I have the project hosted on Google Code and the file can be viewed here. This should help everyone see where everything is at.
Re: Trouble working with Config::Simple
by vendion (Scribe) on Jul 02, 2008 at 01:08 UTC
    I'm still having trouble getting it to write the .kenesis file: I have tryed replacing `$cfg->write("~/.kenesis");` with `$cfg->write("$ENV{HOME}/.kenesis");` and adding `or die $cfg->error();` didn't produce an error. Running $ENV{HOME} through perl -e comes back with the following
    Bareword found where operator expected at -e line 1, near "/etc/bash" (Missing operator before bash?) syntax error at -e line 1, near "/etc/bash" Execution of -e aborted due to compilation errors.
    . I also tried adding in the full path to my home directory and still no file.
      Running this code:
      #!/usr/bin/perl use strict; use warnings; use Config::Simple; our $cfg; my @player; my $completed_quests = "zero"; my $special_item = "zero"; my @enemy; my $class = "zero"; $cfg = new Config::Simple(syntax=>'simple'); $cfg->autosave(1); $cfg->param("player", "@player"); $cfg->param("quest", "$completed_quests"); $cfg->param("items", "$special_item"); $cfg->param("enemy", "@enemy"); $cfg->param("class", "$class"); $cfg->write("$ENV{HOME}/.kenesis");

      outside of my game works but when using it inside the game it doesn't. Maybe it is the way I have it running, right now I have the code for Config::Simple spread out in my main program, but in this test one they are all grouped together variables are created and given a value then everything is written to the file.