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

Helo! I am putting a hash inside of a hash with the result from a split ...
%things = split /-/, $th; push @a, { TITLE => $t, TEXT => $de, EXITS => $ex, THINGS => {%things} + };
For some reason the first key/value pair of the %things is missing .. Anyone can see an obvious mistake I dont see?

Replies are listed 'Best First'.
Re: Lose first element of hash in hash ..
by 7stud (Deacon) on Mar 11, 2010 at 10:09 UTC

    ....besides the fact that most of your variables are not defined?

    use strict; use warnings; use 5.010; my $th = 'hello-10-world-20'; my %things = split /-/, $th; while ( my($key, $val) = each %things ) { say "$key => $val"; } --output:-- hello => 10 world => 20

    What do you consider to be the 'first' key/value pair in a hash?

Re: Lose first element of hash in hash ..
by GrandFather (Saint) on Mar 11, 2010 at 10:12 UTC

    Always use strictures (use strict; use warnings;). I bet turning on warnings is enlightening.


    True laziness is hard work
      7stud, GrandFather, thank you for the quick reply. I have warning and defined variables, I was just simplifying things. YOu are right, there are no first element in a hash (they are stored in an internal order and format, thanks for pointing that out).
      sub initrooms { my (@aa, %things, $b, @ar, $t, $de, $ex, $th, @a); open (RF, "rooms.txt") or die "could not open datafile: $!"; undef $/; @ar = split (/0/, <RF>); $/ = "\n"; foreach (@ar) { ($t, $de, $ex, $th) = split /:/, $_; if ($th eq //) { next; } %things = split /-/, $th; print %things; (all elements present) push @a, { TITLE => $t, TEXT => $de, EXITS => $ex, THI +NGS => {%things} }; } return \@a; } sub lookat { my @i; my ($id, $i, $item); my ($tg, $cr, $aoa) = @_; if (exists ($aoa->[$cr]->{THINGS}->{$tg})) { print color("bold blue"), "\n", $aoa->[$cr]->{THINGS}- +>{$tg}, color("reset"); return; } print "\nHmm .. where?"; }
      In the exist line I can find all things except the first one pushed onto the array. So $aoa->[0]->{THINGS}->{bed} does not exist but $aoa->[0]->{THINGS}->{chair} does exist. Very strange! And this repeats itself in all 3 $aoa[]

        I was going to reverse engineer your code to deduce the format of the data you didn't bother supplying, but your variable names are simply too awful to make that possible in sensible time. Sorry. You are on your own until you can supply a runable script with sample data that shows your problem.


        True laziness is hard work

        I notice some problems that may or may not be connected to the issue at hand:

        1. Instead of globally doing undef $/ and then manually resetting it to a newline, you can do it locally: local $/. By the way, couldn't you just set it to "0" (this is a strange input separator; does the file actually consist of null-terminated strings?)? Further reading: perlvar.
        2. Use telling variable names, e.g. my ($title, $text, $exits, $things). This will save you a lot of time figuring out your own code.
        3. The condition ($th eq //) is a bit odd. Don't you just want to compare with the empty string, ($th eq ""), or match with a regex denoting only whitespace, ($th =~ /^\s*$/)?
        4. It seems like your input for "things" consists of a list of elements in the form "key-value-key-value-key-value". Is that right? You should perhaps show some example input.
        5. Don't use barewords as keys for the hash, use strings like 'title', 'text', 'exit', 'things'.
        6. You seem to intend to create a hash reference for 'things'. This is done with a backslash: ... 'things' => \%things ....
        7. You should close your filehandle when done.
        8. Instead of returning from the function lookat inside the if statement, the clear way of conveying your meaning is to use an else clause.
Re: Lose first element of hash in hash ..
by jethro (Monsignor) on Mar 11, 2010 at 10:32 UTC

    Add

    use Data::Dumper; print Dumper($th,\%things),"\n";

    to your script and enlightenment will follow (probably)

      jethro, thanks for suggesting that .. It produced some interesting output!
      'THINGS' => { 'pillow' => 'Nice soft pillow ..', 'sheets' => 'Long white sheets .. You slept +in them last night. ', ' bed' => 'There is some sheets and a pillow here'
      The one that is missing, kind of falls out of the print instead of being listed nicely togetehr with the other ones. That datadumper is a pretty useful tool! (I learn so much new here everyday :)
        Setting $Data::Dumper::Useqq = 1; would make it clearer, but the issue is that the key is "\nbed" (newline-b-e-d)
        It seems that the key you are looking for is not stored as 'bed' but as '\nbed'.