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

Recently i've been working on a script that parses a file and formats the data and spits it out (and it's a finished piece because it e-mails the results as well ; ) One of the odd things about the data is that if there is a duplicate line we want to keep it and insert some previous data before that line. What i came up with is something like:

# in some loop looking through files if ($duplicate) { $data[$count]{VAl1} = $data[$count-1]{VAL1}; $data[$count]{VAL2} = $data[$count-1]{VAL2}; ... #flag data as being duplicate $data[$count]{VAL1} .= '/duplicate'; } $data[$count]{VALX} = /(par)se_so(me)_(dat)a/; next LOOP;
But the problem i have is that the previous data isn't getting sent into the array (of hashes) before the duplicate is sent into the array. When i run with the debugger it is putting the data into the array (and appending the duplicate flag), but apparently it's not being saved.

The reason i'm using $count to index @data is because i don't know which order the lines will go in, but i can check to make sure everything for one record has been pulled out (records aren't nested, thank whatever god you pray to : ) i never actually assign anything to an individual array spot, however, i'm always assigning to the hash inside the array spot. It's my understanding that this 'autovivifies' the spot in the array.

Since the changes are happening inside an if block my guess is that the newly autovivified entry is lost because it only gets lexical scope, maybe. But all of the data is getting set inside a while loop anyway, so why doesn't it all vanish after the while loop?

So the questions are (after that long intro):
a) am i correct that the changes are local even though the spot in the array is autovivified?
b) is there an elegant (or possibly kludgy-but-gets-job-done) way around this data being lost?

Please (un)confuse me,

jynx

Replies are listed 'Best First'.
(Ovid) Re: local autovivification dismemberment...
by Ovid (Cardinal) on Jan 04, 2001 at 04:20 UTC
    I can't follow what you are looking for. You've provided pseudo-code and left out quite a bit of information that could be useful. For example, VAL1, VAL2, and VALX are barewords being used as keys? Are they constants (with use constant)? Are they scalars, but you left off the dollar signs?

    Also, you appear to have a regex, but without the binding operator: '=' should be '=~'.

    If you supply us with a sample of input data and what the resulting data structure should look like, that would help.

    Cheers,
    Ovid

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

      please disregard this question,

      Your questions prompted me to do a complete write and as soon as i rewrote what i was doing it became clear (since i was also trying to explain what i was doing in the post to make sure it was clear). Thank you for asking the question you did, it actually made me think of things in a way i wouldn't have normally.

      i will ++ you tomorrow when i have more votes (and Fastolfe as well, his questions were just as valid!). Thanks all around, your confusion answered my question (so to speak)...

      jynx

Re: local autovivification dismemberment...
by Fastolfe (Vicar) on Jan 04, 2001 at 04:37 UTC
    I'm having a lot of trouble following, but if I understand it, @data contains one element per line of 'stuff', where that 'stuff' is parsed into multiple fields (hash keys VAL1, VAL2, etc.). Somehow, you figure out that line $count is a duplicate of $count-1, so you set its fields equal to the one before it, appending "/duplicate" to its first field. Am I right so far?

    If that's the case, I can't see any reason why this would be giving you problems. Unless you've explicitely scoped this stuff locally, it shouldn't be disappearing. I think we definitely need to see some more code and context to be able to know what's going on. Some debugging code before, in, and after your 'if' block might be helpful too, and should rule out your scoping hypothesis.