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

Hello Monks,
I'm trying to make a Fighting Fantasy Game (books published in '80) base system with perl. However something seems to be stuck completely on loading (Data::dumber+eval). Load it self works nicely, however when i'm trying to read info on all equipment that player has, my regex fails. But when i'm using the same sub with 'perl -e' it works (used to use it in player creating and it worked there as well).

Now i'm not going to put all code here. Reasons being that it's currently about 1000 lines long (4 modules) and texts are in finnish (i own the book in finnish...). And it's still work in progress (and i've learned nicely while doing this so far). But here is the relevant parts of it.
# in Equipment.pm ############### # Read an equipment from file to memory sub read_eq ($) { my $eq=shift @_; return if (exists($eq_list{$eq})); local $_; # use re "debug"; open (EQF,"$eq_file") or die "$!"; while (<EQF>) { (m/^#/o) && next; chomp; if (m/^$eq/) { my @array=split (/::/,$_); $eq_list{$eq}=[@array[1 .. $#array]]; $eq=0; last; } } close EQF; if ($eq) { warn "Unable to find equipment \'$eq\'\n"; } return; } # Reads all equipments from player into memory sub read_player () { local $_; foreach (Player::list_all ()) { read_eq ($_); } return; }
Now the Player::list_all () return a list of numbers which match to an eq in 'eq.list' file. Which has that number as first thing (or '#' meaning comment line). When i do this i get proper (no notifications) answer.
perl -e 'use Equipment;@a=(5,1,6,4);foreach (@a) { Equipment::read_eq( +$_); }'
But if i use the Equipment::read_player (), it prints "Unable to find equipment 'X'" for each equipment. Heres the format for 'eq.list' file. Numbers are in the first column in each row (separator is '::').
# list of equipment, that game uses
# comments can be added with '#' in the beginning
1::voimajuoma::potion::orig_const|const::0::0::0
2::taitojuoma::potion::orig_skill|skill::0::0::0
3::onnijuoma::potion::orig_luck+1|luck::0::1::0
4::ruoka::food::+4|const::0::0::0
5::miekka::weapon::::0::0::2
6::nahkahaarniska::armour::::0::0::2

I took some debug from regex (using 'use re "debug";') and this is relevant part.
Guessing start of match, REx `^#' against `# list of equipment, that game uses
# comments can be added ...'...
Guessed: match at offset 0
Matching REx `^#' against `# list of equipment, that game uses
# comments can be added ...'
  Setting an EVAL scope, savestack=85
   0 <> <# list of eq>    |  1:  BOL
   0 <> <# list of eq>    |  2:  EXACT <#>
   1 <#> < list of eq>    |  4:  END
Match successful!
Unable to find equipment '5'
Guessing start of match, REx `^#' against `# list of equipment, that game uses
# comments can be added ...'...
Guessed: match at offset 0
Matching REx `^#' against `# list of equipment, that game uses
# comments can be added ...'
  Setting an EVAL scope, savestack=85
   0 <> <# list of eq>    |  1:  BOL
   0 <> <# list of eq>    |  2:  EXACT <#>
   1 <#> < list of eq>    |  4:  END
Match successful!
Unable to find equipment '1'
And so on for each equipment.
TIA

Replies are listed 'Best First'.
Re: Regex: same code works and fails, why?
by Abigail-II (Bishop) on Jan 07, 2004 at 15:22 UTC
    The debug output suggests that you have read in the entire file at once ($/ being undefined?). Hence, m/^#/ matches (no need for /o here, or the parens), next is performed, but there's no next line, so no equipment to be found.

    Abigail

      You're right.
      Huge Thanks.

      I do have in my load function 'local $/;' to use eval on file which is made by Data::Dumper->Dump. And then continue to use 'Equipment::read_player();' without resetting $/ :).

      Shouldn't the /o make it faster (in theory)? Parens i use, because it makes the line more readable for me atleast.
        What makes you think the /o makes it faster? Is there some wrong documentation suggesting it does?

        Abigail